1. 程式人生 > >NodeJS框架express的HTTP方法和錯誤處理

NodeJS框架express的HTTP方法和錯誤處理

HTTP方法

在CSSer前面的文章中我們已經接觸過app.get()多次了,同時Express也提供了對其它HTTP動作的封裝,如app.post(), app.del()等。

對於POST最常見的例子,就是當我們提交一個表單時,下面我們在HTML中將表單的method特性設定為“post”,然後需要在服務端定義對該表單提交的路由控制。

<form method="post" action="/">
    <input type="text" name="user[name]" />
    <input type="text" name="user[email]" />
    <input type="submit" value="Submit" data-description="csser.com" />
</form>

預設情況下Express並不知道該如何處理該請求體,因此我們需要增加bodyParser中介軟體,用於分析application/x-www-form-urlencoded和application/json請求體,並把變數存入req.body。我們可以像下面的樣子來“使用”中介軟體:

app.use(express.bodyParser());

接下來下面的路由就可以訪問req.body.user物件了,該物件包含客戶端提交的name和email屬性。

app.post('/', function(req, res){
  console.log(req.body.user);
  res.redirect('back');
});

要在表單中使用PUT的HTTP方法,我們可以利用名為_method的隱藏表單域,它能改變HTTP方法。而在服務端,我們首先需要利用methodOverride中介軟體,把它放在bodyParser中介軟體下方,從而可以利用包含表單值的req.body。

app.use(express.bodyParser());
app.use(express.methodOverride());

之所以需要這樣做,是因為這些處理並不總是預設進行的,原因很簡單,因為這些對Express的整體功能來說並不是必需的,依據應用的具體需求,你並不一定需要這些功能,如果客戶端直接支援PUT和DELETE方法也可以被直接訪問到,同時methodOverride為表單提供了強大的解決方案,下面我們展示下PUT的使用:

<form method="post" action="/">
  <input type="hidden" name="_method" value="put" />
  <input type="text" name="user[name]" />
  <input type="text" name="user[email]" />
  <input type="submit" value="Submit" />
</form>

app.put('/', function(){
    console.log(req.body.user);
    res.redirect('back');
});

錯誤處理

Express提供了app.error()方法來接收路由或傳入next(err)的異常,下面的示例為不同的頁面提供專門的NotFound異常服務:

function NotFound(msg){
  this.name = 'NotFound in csser.com';
  Error.call(this, msg);
  Error.captureStackTrace(this, arguments.callee);
}

NotFound.prototype.__proto__ = Error.prototype;

app.get('/404', function(req, res){
  throw new NotFound;
});

app.get('/500', function(req, res){
  throw new Error('keyboard cat!');
});

像下面一樣,我們可以多次呼叫app.error(),這裡我們檢查如果是NotFound例項就顯示404頁面,否則將其傳入下一個錯誤處理。

注意這些處理可以定義在任何地方,它們可以放在路由可以listen()之處。這也允許在configure()塊內做定義,於是我們就可以以不同的基於環境的方式處理異常。

app.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.jade');
    } else {
        next(err);
    }
});

下面的演示我們假設所有錯誤都為500錯誤,但你可以根據喜好選擇。例如當node在處理檔案系統呼叫時,就有可能接收到這樣的錯誤物件,其ENOENT的error.code為“no such file or directory”,這時我們可以在錯誤處理函式中進行處理然後顯示特定的頁面給使用者。

app.error(function(err, req, res){
   res.render('500.jade', { error: err });
});

我們的應用也可以利用Connect errorHandler中介軟體來彙報異常資訊。例如我們想在“開發”環境輸出異常到stderr:

app.use(express.errorHandler({ dumpExceptions: true }));

同時在開發期間我們想用好看的HTML頁面顯示異常資訊時,可以設定showStack的值為true:

app.use(express.errorHandler({ showStack: true, dumpExceptions: true }));

如果請求頭支援application/json,errorHandler中介軟體也能以json方式做出響應,這對依賴於客戶端Javascript的應用開發很有益處。