Express的Middleware

Middleware(中間件)是Express中一個很是核心的概念。理解其工做原理對於編寫能夠維護網站、減小代碼量具備很是重要的做用。css

什麼是Middleware?

從實現上看,Middleware和Route Handler同樣,本質上都是函數。Middleware這個函數接受express傳入3個參數:req,res和next。調用的方法就是app.use(function(req,res,next){....});
從處理過程上來看,middleware是處在請求Request和最終處理請求的Route Handler之間的一系列函數,它對於請求的內容在交由Route Handler以前作預先的處理。例以下面在請求到達route handler處理以前,經由Middleware的處理將請求的方法和地址打印在console中。數據庫

var app = express();

app.use(function(req, res, next) {
  console.log('%s %s', req.method, req.url);
  next();
});

app.get('/', function(req, res, next) {
  res.send('Hello World!');
});

app.get('/help', function(req, res, next) {
  res.send('Nope.. nothing to see here');
});

固然這只是一個很是簡單的例子,實際上express提供的Middleware能夠實現很是強大的處理功能,例如對於session的管理等等。在具體本身動手寫一個Middleware以前,不妨先去找找已經成熟的Middleware,畢竟express的社區是很是活躍的。express

Middleware的參數

res, req

req和res分別表明請求和響應的對象的直接引用,這個概念很是重要,可是暫時且放在一邊,先來看第3個參數next。cookie

Next()

當調用next的時候,express將執行下一個Middleware。爲何不能像通常的js函數同樣執行完畢就進入下一個Middleware,而要經由next來實現呢?
這是由於Middleware中有可能會執行異步的操做(例如對數據庫的讀寫等等),因此並不是到達函數底部就表明Middleware執行的完成,而應該將異步的操做完成才視做整個Middleware處理的完成。因爲express並不知道操做什麼時候算是完成,所以必須等到next函數被顯性的呼叫以後,纔會進入下一個Middleware的處理。
若是忘記調用next(),則會致使請求沒法繼續進行處理的錯誤。(固然,若是執行res.end又是另當別論的事情了)session

Middleware使用中容易出現的錯誤

一、Middleware的順序很是重要。
Middleware是按照順序調用,所以若是調用的順序不當極可能出現錯誤。另外若是將Route handler與Middleware混用,會致使在middleware之上部分的route不會執行這個middleware的內容。例以下面的代碼中,向根節點的get請求就不會經由Middleware進行處理。app

app.get('/', function(req, res) { res.send('hello'); });

app.use(function(req, res, next) {
  next();
});

app.post('/', function(req, res) { res.send('bye'); });

另外一個更爲常見的例子是static file server這個Middleware,由於咱們沒法爲每個資源文件,例如js,css寫單獨的routing,這個Middleware能夠實現到指定的文件夾下尋找對應的文件,一旦找到對應的文件則會返回這個文件。若是將這個操做放在全部session處理的Middleware以前,則返回的文件不會請求新的session,可能會致使cookie設置不上。所以習慣性的將這個Middleware放在全部的Middleware以後使用。
二、忘記調用Next()
三、Req和Res都是對對象的直接引用。任何添加、刪除、覆蓋的操做都會由於它們是對對象的引用而反映到下一個Middleware以及以後route handler中。異步

後記

Express4.x對於Middleware的功能進行了一些加強,同時將大部分原來默認搭載的Middleware移除,僅保留了最核心的Routing功能。進一步瞭解Express3.x到4.x的異同,參見《Express 4.x的特性和3.x的遷移》函數

參考文章:
《Express.js Middleware Demystified》
https://blog.safaribooksonline.com/2014/03/10/express-js-middleware-demystified/
post

相關文章
相關標籤/搜索