2013年6月22日 星期六

About HTTP delete method error response

記錄一個比較不常用到的操作方式...
以client使用request module為例...
http delete method中,某些client遇到error時,解讀回覆部分不是直接取用body
而是去解析error物件來做回覆
此時如何從server端製作一個錯誤來讓client操作呢...

下面是client端的模擬code,主要client端想要取出callback function中的error物件...

Client side:
var opts = {url:'http://localhost:1337/test/123', method:'DELETE'};
request(
  opts, 
  function(error,res,body) {
    console.log(e);
  }
);

此時server side的實作,以express為例,只需要在res.send()中依序帶入:
  • 第一個欄位設定錯誤代碼
  • 第二個欄位為錯誤物件描述,建議以JSON為格式(預設格式為{code: xxx, message:xxx},若符合此格式,回覆時候匯自動取message內文做為error的message欄位,並會在error物件中多一個code的欄位}
下面模擬del協定,於呼叫時候丟錯:

Server side:
app.del('/test/:id', function(req, res) {
  res.send(400, {code:"test error", message:"the tested error"});
});

此時client的console pring匯出現下面訊息:

Client result: 
{ message: 'the tested error',
  body: { code: 'test error', message: 'the tested error' },
  httpCode: 400,
  statusCode: 400,
  restCode: 'test error',
  code: 'test error' }

如上描述,如果server改寫response回傳物件(不使用預設格式)...

Server side:
app.del('/test/:id', function(req, res) {
  res.send(400, {coder:"test error", msg:"the tested error"});
});

則,error物件會長這樣子:

{ message: '{\n  "coder": "test error",\n  "msg": "the tested error"\n}',
  body: { coder: 'test error', msg: 'the tested error' },
  httpCode: 400,
  statusCode: 400 }

Log4js support print object inline

log4js套件是我常使用的log管理工具
最近看別人的程式才發現,原來它有支援物件的列印
透過 log.info('......%o....', jsonObject) 的方式
可以直接把物件解析成String...
真是方便的功能∼

範例:

執行結果:


更正,不是%o造成的
應該是log4js將最後一個參數使用像console.log(object)的方式
解些json物件成為string...

2013年6月11日 星期二

Access-Control-Allow-Origin範例

在JS的世界裡,Ajax的頭號天敵就是為了避免不安全,Browser所設限的coss site not allow的限制,為了避免cross site javascript的問題,傳統作法是透過script tag來嵌入非同個網站的資源,或是使用jsonp來做site to site的呼叫,但是...

  • script tag內文必須要是script,否則無法順利讀取,甚至會弄壞網頁中的js...
  • jsonp已經被chrome排擠... firefox可以正常使用
有了Node.js的request套件後,我們大可以一行解決... 讓遠方資源變成我發資源:
request.get('http://mysite.com/doodle.png').pipe(resp)
上面可以讓原本需要透過http://mysite.com/doodle.png 來呼叫的資源,透過你制定的鏈結呼叫該資源...
而,根本的解決方式可以使用Header中加入Access-Control-Allow-Origin參數來設定你的js,允許讓其他網站來呼叫...
Server端實作:

See:/examples/basic/http/cross-site-server.js

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200,{"Access-Control-Allow-Origin": "http://10-20-0-31.my.micloud.tw"});
  res.end(JSON.stringify({result:'yes'}));
}).listen(8080);
console.log('Server running at port 8080');
上面設定資源可以讓site:http://10-20-0-31.my.micloud.tw 下面的網頁來呼叫,如果想要讓所有網站都可以呼叫,可以使用"*"來讓所有網站可以呼叫...
Client端實作:

See:/examples/basic/http/cross-site.html

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(document).ready(function(){
  $.getJSON('http://211.78.254.38:8080/', function(data){
    $('#r').html(data.result);
  });
});
</script>
<h1>Server response: <span id="r"></span></h1>