使用中間件
應用級中間件:
應用級中間件綁定到 app 對象 使用 app.use()
和 app.METHOD()
, 其中, METHOD
是需要處理的 HTTP 請求的方法,例如 GET, PUT, POST 等等,全部小寫。例如:
var app = express();
// 沒有掛載路徑的中間件,應用的每個請求都會執行該中間件
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 掛載至 /user/:id 的中間件,任何指向 /user/:id 的請求都會執行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 路由和句柄函數(中間件系統),處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
下面這個例子展示了在一個掛載點裝載一組中間件。
// 一個中間件棧,對任何指向 /user/:id 的 HTTP 請求打印出相關信息
app.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
作為中間件系統的路由句柄,使得為路徑定義多個路由成為可能。在下面的例子中,為指向 /user/:id 的 GET 請求定義了兩個路由。第二個路由雖然不會帶來任何問題,但卻永遠不會被調用,因為第一個路由已經終止了請求-響應循環。
// 一個中間件棧,處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
console.log('ID:', req.params.id);
next();
}, function (req, res, next) {
res.send('User Info');
});
// 處理 /user/:id, 打印出用戶 id
app.get('/user/:id', function (req, res, next) {
res.end(req.params.id);
});
如果需要在中間件棧中跳過剩余中間件,調用 next('route') 方法將控制權交給下一個路由。 注意: next('route') 只對使用 app.VERB() 或 router.VERB() 加載的中間件有效。
// 一個中間件棧,處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
// 如果 user id 為 0, 跳到下一個路由
if (req.params.id == 0) next('route');
// 否則將控制權交給棧中下一個中間件
else next(); //
}, function (req, res, next) {
// 渲染常規頁面
res.render('regular');
});
// 處理 /user/:id, 渲染一個特殊頁面
app.get('/user/:id', function (req, res, next) {
res.render('special');
});
路由級中間件
路由級中間件和應用級中間件一樣,只是它綁定的對象為 express.Router()。
var router = express.Router();
路由級使用 router.use() 或 router.VERB() 加載。
上述在應用級創建的中間件系統,可通過如下代碼改寫為路由級:
var app = express();
var router = express.Router();
// 沒有掛載路徑的中間件,通過該路由的每個請求都會執行該中間件
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 一個中間件棧,顯示任何指向 /user/:id 的 HTTP 請求的信息
router.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 一個中間件棧,處理指向 /user/:id 的 GET 請求
router.get('/user/:id', function (req, res, next) {
// 如果 user id 為 0, 跳到下一個路由
if (req.params.id == 0) next('route');
// 負責將控制權交給棧中下一個中間件
else next(); //
}, function (req, res, next) {
// 渲染常規頁面
res.render('regular');
});
// 處理 /user/:id, 渲染一個特殊頁面
router.get('/user/:id', function (req, res, next) {
console.log(req.params.id);
res.render('special');
});
// 將路由掛載至應用
app.use('/', router);
錯誤處理中間件
錯誤處理中間件有 4 個參數,定義錯誤處理中間件時必須使用這 4 個參數。即使不需要 next 對象,也必須在簽名中聲明它,否則中間件會被識別為一個常規中間件,不能處理錯誤。
錯誤處理中間件和其他中間件定義類似,只是要使用 4 個參數,而不是 3 個,其簽名如下: (err, req, res, next)。
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
內置中間件
從 4.x 版本開始,, Express 已經不再依賴 Connect 了。除了 express.static
, Express 以前內置的中間件現在已經全部單獨作為模塊安裝使用了。請參考 中間件列表。
express.static
是 Express 唯一內置的中間件。它基于 serve-static,負責在 Express 應用中提托管靜態資源。
參數 root
指提供靜態資源的根目錄。
可選的 options
參數擁有如下屬性。
屬性 | 描述 | 類型 | 缺省值 |
---|---|---|---|
dotfiles |
是否對外輸出文件名以點(. )開頭的文件。可選值為 “allow”、“deny” 和 “ignore” |
String | “ignore” |
etag |
是否啟用 etag 生成 | Boolean | true |
extensions |
設置文件擴展名備份選項 | Array | [] |
index |
發送目錄索引文件,設置為 false 禁用目錄索引。 |
Mixed | “index.html” |
lastModified |
設置 Last-Modified 頭為文件在操作系統上的最后修改日期。可能值為 true 或 false 。 |
Boolean | true |
maxAge |
以毫秒或者其字符串格式設置 Cache-Control 頭的 max-age 屬性。 | Number | 0 |
redirect |
當路徑為目錄時,重定向至 “/”。 | Boolean | true |
setHeaders |
設置 HTTP 頭以提供文件的函數。 | Function |
下面的例子使用了 express.static
中間件,其中的 options
對象經過了精心的設計。
var options = {
dotfiles: 'ignore',
etag: false,
extensions: ['htm', 'html'],
index: false,
maxAge: '1d',
redirect: false,
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now());
}
}
app.use(express.static('public', options));
每個應用可有多個靜態目錄。
app.use(express.static('public'));
app.use(express.static('uploads'));
app.use(express.static('files'));
更多關于 serve-static
和其參數的信息,請參考 serve-static 文檔。
第三方中間件
通過使用第三方中間件從而為 Express 應用增加更多功能。
安裝所需功能的 node 模塊,并在應用中加載,可以在應用級加載,也可以在路由級加載。
下面的例子安裝并加載了一個解析 cookie 的中間件: cookie-parser
$ npm install cookie-parser
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
// 加載用于解析 cookie 的中間件
app.use(cookieParser());
請參考 第三方中間件 獲取 Express 中經常用到的第三方中間件列表