2012年7月23日 星期一

NPM using proxy

在使用NPM指令時候,如果剛好在個有Proxy的區域
常常npm會有問題,Linux的使用者會這麼做:

export HTTP_PROXY=http://your.proxy.ip.address:port

讓程是預設吃這個位置的proxy設定
但是Windows的使用者一般都是到網路管理界面設定...
這部分NPM連線就有問題
作法很簡單,Windows中的NPM也吃HTTP_RPOXY這個參數
所以只要這樣做:

set HTTP_PROXY=http://your.proxy.ip.address:port

就可以正常使用NPM了...

當然∼要確認NPM的repository是否可以辨識得到(這部分是跟DNS有關)


如果不小心被DNS漏掉,可以加到static route去(/etc/hosts或C:\Windows\system32\drivers\etc\hosts)
他的IP可以這樣查:

nslookup registry.npmjs.org 8.8.8.8

其中8.8.8.8是Google的DNS服務...將查到的IP寫到static route去就可以摟∼

2012年7月17日 星期二

JSON object in node.js

在Node.js/JavaScript中
針對JSON物件可以用這樣的方法循序倒出來

$ node
> var json = { "aa":1, "bb":2,"cc":3}
> for(key in json){
... console.log(key);
... }
aa
bb
cc
> 

2012年6月5日 星期二

Apache官方支援的Node.js API for CouchDB

Apache官方支援的Node.js API for CouchDB : cradle
下面是實作範例
Shcema設計:
  • key的部分固定使用uuid + @ + name:
  • 另外一個附屬欄位description作為文件描述

實作:
var util = require('util');
var cradle = require('cradle');

//連線資訊設定
var port = 5984;
var options = {
  cache : true,
  raw : false,
  auth: { username: 'username', password: 'password' }
};

//開啟DB
var db = new(cradle.Connection)(url, port, options).database('snapshot_logger');

/**
  * 取得document
  */
exports.getSnapshotDescript = function(uuid, name, callback){
  var snapname = util.format('%s@%s',uuid, name);
  db.get(snapname, function (err, doc) {
    var result = {}
    if(err){
      result.msg = 'error';
      result.error = err;
    }else {
      result.msg = 'success';
      result.doc = doc;
    }

    callback(result);
  });
};

/**
 * 儲存或更新一筆資料
 */
exports.saveSnapshotDescript = function(uuid, name, descript, callback) {
  var snapname = util.format('%s@%s',uuid, name);
  var data =
    {
      snapname: snapname,
      uuid: uuid,
      descript: descript
    };

  var result = {};
  db.save(snapname,
    data,
    function (err, res) {
      if (err) {
        result.msg = 'error';
        result.err = err;
      } else {
        result.msg = 'success';
        result.doc = res;
      }
      callback(result);
  });
};

/* 刪除一筆資料 */
exports.delSnapshotDescript = function(uuid, name, callback) {
  var snapname = util.format('%s@%s',uuid, name);
  var result = {};
  this.getSnapshotDescript(uuid, name, function(result){
    if(result.doc) {
      db.remove(snapname, function (err, res) {
        console.log(res);
      });
    } else {
      result.msg = 'warning';
      result.log = util.format('[Warning]Doc not found of _id:%s',snapname);
    }
    callback(result);
  });
}



使用方式:
/* Save or update document */
this.saveSnapshotDescript(uuid,name,'TEST 1234', function(result){
  console.log('Something done...');
  console.log('Save result.... %s', JSON.stringify(result));
}); 

/* Delete Document */
this.delSnapshotDescript(uuid,name, function(result){
  console.log( JSON.stringify(result));
}); 

/* Get Document */
this.getSnapshotDescript(uuid, name, function(res) {
  console.log('Get result:' + JSON.stringify(res));
});

2012年5月31日 星期四

使用原生的http request進行post form呼叫

使用原生的http request進行post form呼叫:

var qs = require('querystring');
var http = require('http');

// Base authentication
var username = 'your_username';
var password = 'your_password';
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');

// The connection parameters
var opts = {
 host:"your.server.ip.address",
 port: 80,
 method: 'POST',
 path: "/your_path",
 headers :
  {
    "Authorization": auth ,
    "Content-Type":"application/x-www-form-urlencoded; charset=utf-8",
    "Content-Length": 0
  }
};

// Example function
exports.your_function = function(param1, ..., callback){
  // Process your business logic for params...
  // The post form parameters
  var form_params = {
    field1 : "value 1",
    field2 : "value 2",
    ...
  };

  var params = qs.stringify(form_params);
  opts.headers['Content-Length'] = params.length;

  var req = http.request(opts, function(res){
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    res.setEncoding('utf8');
  });

  req.on('response', function(res){
    res.body = '';
    res.setEncoding('utf-8');
    res.on('data', function (chunk) {
      res.body += chunk;
    });
    
    // Trigger the callback
    res.on('end', function(){
      callback(res.body, res);
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write(params);
  req.write('data\n');
  req.end();
}

// Usage of sample function
this.your_function(
    param1, ..., 
    function(body, res){
      console.log(body);
      console.log('>>>>>>>>>>>'+res.headers['Content-Type']);
    }
);

使用request套件進行http post request

使用request套件進行http post request,範例中始用到HTTP Base Authentication,如無需要,可移除Headers中的Authorization部分敘述:

1. 安裝request套件
npm install request

2. 範例執行檔案
var request = require('request');
var qs = require('querystring');

// Base Authentication
var username = 'yourname';
var password = 'yourpasswd';
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');

// Base url of you will request (include protocol, address, port, path and the lastest of '?')

// Your form fields 
var params = {
  field_A : "value a",
  field_B : "value b",
  headers: { "Authorization": auth }
}

// Append query string to your url
url += qs.stringify(params);

// Your customize function
exports.your_function1 = function(param1,..., callback) {
  //process params...
  request.post(url, params, function (e, r, body) {
      if(callback)
        callback(e, r, body);
  });
}

// Usage of your customize function:
this.your_function1(param1, ..., function(e,r,body) {
  //Process your responses
  //ex:
  console.log(body);
  console.log(r.headers['Content-Type']);
});

2012年5月7日 星期一

The Smallest Web Server Demo

Node.js官網上常常掛著Node.js的Simplest Web Server Demo
這邊把它修改一下,頁面加上顯示IP資訊
方便做為雲端多主機部署程式時檢查之用

var http = require('http');
var os = require('os');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('My Address: '+JSON.stringify(os.networkInterfaces().net0[0].address));
}).listen(1337);
console.log('Server running at http://127.0.0.1:1337/');

連線時,只要瀏覽器列打上 http://your_ip_address:1337
就可以看到如下圖的資訊



其中network interface的顯示依平台與設定而不同,在Mac上顯示資訊如下:

{ lo0: 
   [ { address: 'fe80::1', family: 'IPv6', internal: true },
     { address: '127.0.0.1', family: 'IPv4', internal: true },
     { address: '::1', family: 'IPv6', internal: true } ],
  en0: 
   [ { address: 'fe80::1240:f3ff:fe8b:a9bc',
       family: 'IPv6',
       internal: false },
     { address: '192.168.1.106', family: 'IPv4', internal: false } ] }

而筆者的另一個平台顯示如下:

 [root@simon001 ~/TestPrj]# node
> var os = require('os');
> os.networkInterfaces()
{ lo0: 
   [ { address: '127.0.0.1',
       family: 'IPv4',
       internal: true },
     { address: '::1',
       family: 'IPv6',
       internal: true } ],
  net0: 
   [ { address: '211.78.255.31',
       family: 'IPv4',
       internal: false } ] }

因此,如果要實作不同平台的程式,可要注意這些差異喲∼ 

2012年5月3日 星期四

Node.js using prototype

雖然跟prototype不熟,不過知道他是JavaScript中重要的角色
Node.js可以直接使用喔∼
下面是一個範例,提供讓string物件直接有endsWith的function...
您可以直接放在程式碼中,或是放到library裡面再require進來

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

使用方法: 直接在string物件的後面.endsWith就可以摟∼

var str = 'abc123';
if(str.endsWith('123')) {
  console.log('Yes, endsWith "123"!');
}