第一篇:瞭解Nodejs架構Express——路由,中介軟體
- 路由
路由是指如何定義應用的端點(URIs)以及如何響應用戶端的請求。
路由是由一個 URI、HTTP 要求(GET、POST等)和若干個控制代碼組成,它的結構如下: app.METHOD(path, [callback…], callback), app 是 express 對象的一個執行個體, METHOD 是一個 HTTP 要求方法, path 是伺服器上的路徑, callback 是當路由匹配時要執行的函數。
基本路由樣本:
var express = require('express');var app = express();//app是Express的一個執行個體對象// respond with "hello world" when a GET request is made to the homepageapp.get('/', function(req, res) { res.send('hello world');});
路由方法
Express 定義了如下和 HTTP 要求對應的路由方法: get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search, 和 connect。
有些路由方法名不是合規的 JavaScript 變數名,此時使用括弧記法,比如: app[‘m-search’](‘/’, function …)
app.all() 是一個特殊的路由方法,沒有任何 HTTP 方法與其對應,它的作用是對於一個路徑上的所有請求載入中介軟體。
app.all('/secret', function (req, res, next) { console.log('Accessing the secret section ...'); next(); // pass control to the next handler});
在下面的例子中,來自 “/secret” 的請求,不管使用 GET、POST、PUT、DELETE 或其他任何 http 模組支援的 HTTP 要求,控制代碼都會得到執行。
路由路徑
路由路徑和要求方法一起定義了請求的端點,它可以是字串、字串模式或者Regex。
上述樣本中 “/secret”即路由路徑。
路由控制代碼
可以為請求處理提供多個回呼函數,其行為類似 中介軟體。唯一的區別是這些回呼函數有可能調用 next(‘route’) 方法而略過其他路由回呼函數。可以利用該機製為路由定義前提條件,如果在現有路徑上繼續執行沒有意義,則可將控制權交給剩下的路徑。
混合使用函數和函數數組處理路由:
var cb0 = function (req, res, next) { console.log('CB0'); next();}var cb1 = function (req, res, next) { console.log('CB1'); next();}app.get('/example/d', [cb0, cb1], function (req, res, next) { console.log('response will be sent by the next function ...'); next();}, function (req, res) { res.send('Hello from D!');});
下表中響應對象(res)的方法向用戶端返迴響應,終結請求響應的迴圈。如果在路由控制代碼中一個方法也不調用,來自用戶端的請求會一直掛起。
使用中介軟體
Express 是一個自身功能極簡,完全是由路由和中介軟體構成一個的 web 開發架構:從本質上來說,一個 Express 應用就是在調用各種中介軟體。
中介軟體(Middleware) 是一個函數,它可以訪問請求對象(request object (req)), 響應對象(response object (res)), 和 web 應用中處於要求-回應迴圈流程中的中介軟體,一般被命名為 next 的變數。
中介軟體的功能包括:
執行任何代碼。
修改請求和響應對象。
終結要求-回應迴圈。
呼叫堆疊中的下一個中介軟體。
如果當前中介軟體沒有終結要求-回應迴圈,則必須調用 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, 列印出使用者 idapp.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.static(root, [options])
express.static 是 Express 唯一內建的中介軟體。它基於 serve-static,負責在 Express 應用中提託管靜態資源。
可選的 options 參數擁有如下屬性。
app.use(express.static(path.join(__dirname, "bower_components")));//靜態資源檔案夾
第三方中介軟體
下面的例子安裝並載入了一個解析 cookie 的中介軟體: cookie-parser
$ npm install cookie-parser
var express = require('express');var app = express();var cookieParser = require('cookie-parser');
// 載入用於解析 cookie 的中介軟體
app.use(cookieParser());