一個請求發送到服務器,要經歷一個生命週期,服務端要: 監聽請求-解析請求-響應請求,服務器在處理這一過程的時候,有時候就很複雜了,將這些複雜的業務拆開成一個個子部分,子部分就是一個個中間件。對於處理請求來講,在響應發出以前,能夠對請求和該級響應作一些操做,而且能夠將這個處理結果傳遞給下一個處理步驟node
執行任何代碼。
修改請求和響應對象。
終結請求-響應循環。
調用堆棧中的下一個中間件
應用級中間件
路由級中間件
錯誤處理中間件
內置中間件
第三方中間件
var express = require('express'); var app = express(); app.get('/', function(req, res, next) { // req 修改請求 // res 響應對象 next(); // 當前中間件函數沒有結束請求/響應循環, 調用next(), // 將控制權傳遞給下一個中間件函數繼續往下處理,不然頁面到此會被掛起 }); app.get('/end', function(req, res) { res.send('程序到我這裏就結束了,沒有next方法'); }) app.listen(3000);
上面next()的說明: next()函數不是nodejs或者express的函數,而是傳遞中間件函數的第三變量,它是一個統稱,能夠爲任意名稱,爲了名稱統一,不形成混淆,約定爲next(),調用它以後會將調用應用程序中的下一個中間件程序express
var express = require('express'); var app = express(); app.use(requestTime); // var requestTime = function(req,res, next) { req.requestTime = new Date().getTime(); next(); } app.get('/time', function(req, res, next) { var timeText = '當前時間爲:'; timeText = timeText + req.requestTime; // 這裏的req.requestTime 是上一個中間件函數傳遞過來的, // 一個業務處理流程,多箇中間件函數對請求 req進行修改處理,而且經過next() 傳遞給下一個中間件函數, // 這樣下面的中間件函數都能拿到上一個中間件函數處理的結果 res.send(timeText); }); app.get('/end', function(req, res) { res.send('程序到我這裏就結束了,沒有next方法'); }) app.listen(3000);
下面是多箇中間件函數,在各自函數中處理請求和響應的例子:服務器
var express = require('express'); var app = express(); var middleA = function (req, res, next) { req.useOne = '應用程序通過了 middleA '; res.useOne = 'middleA 處理後的數據 middleA'; req.paramasQuery = 1 // console.log(req.useOne, req.useTwo, req.useThree); next(); } var middleB = function (req, res, next) { req.useTwo = '應用程序又通過了 middleB'; res.useTwo = 'middleB 處理後的數據 middleB'; req.paramasQuery += 1; console.log(res.useOne, res.useTwo, res.useThree); next(); } var middleC = function (req, res, next) { req.useThree = '應用程序又通過了 middleC'; res.useThree = 'middleC 處理後的數據 middleC'; req.paramasQuery += 2; console.log(res.useOne, res.useTwo, res.useThree); console.log(req.paramasQuery); next(); } app.use(middleA); app.use(middleB); app.use(middleC); app.get('/', function(req, res, next) { console.log(req.useOne, req.useTwo, req.useThree); // 應用程序通過了 middleA 應用程序又通過了 middleB 應用程序又通過了 middleC // 上面的req裏面的參數就是在 不一樣的中間件函數中處理出來的 console.log(res.useOne, res.useTwo, res.useThree); // middleA 處理後的數據 middleA middleB 處理後的數據 middleB middleC 處理後的數據 middleC // 上面的res的響應參數也是在上面一個個中間件的響應res中逐步處理 累加而得 req.paramasQuery += 3; // req中paramasQuery的參數通過中間不一樣的中間件函數處理,已經累加到7, // 同理對於res 採用相同的處理方式,也能夠達到這樣的效果 // 咱們以此能夠推出,若是處理一個很複雜的程序時,咱們一箇中間件函數只處理一個步驟, // 而且能夠把該步驟處理後的結果,傳遞給下一個中間件函數處理, // 一種流水線的處理方式,職責專注,效率很快 res.send('req.paramasQuery 通過不一樣的中間件處理後的結果是:' + req.paramasQuery); // 7 }) app.listen(5000, function() { console.log('5000 端口啓動了') })
express 中間件函數,幫助拆解主程序的業務邏輯,而且每個的中間件函數處理的結果都會傳遞給下一個中間件函數。想象一下工廠上流水線工人,在清洗一個箱子的一個場景。第一我的清洗側面,第二我的清洗底面,第三我的清洗頂面,。。。,這條流水線結束後,箱子也就清洗乾淨了。
各作各的,不相互影響,又彼此協做。app