關於express中間件的簡要解析之應用級、路由級中間件(一)

      Express 是一個自身功能極簡,完全是由路由和中間件構成一個的 web 開發框架:從本質上來說,一個 Express 應用就是在調用各種中間件。中間件(Middleware) 是一個函數,它可以訪問請求對象(request object (req)),響應對象(response object (res)), 和 web 應用中處於請求-響應循環流程中的中間件,一般被命名爲 next 的變量。

中間件可以分爲以下五種:

  1. 應用級中間件
  2. 路由級中間件
  3. 錯誤處理中間件
  4. 內置中間件
  5. 第三方中間件

        爲加深理解需要做一些實例,首先要建立nodejs express 工程,在工程下隨意創建一個目錄,在該目錄下建立三個文件 server.js、app.js和router.js。

server.js代碼如下:

var http=require('http');

var app=require('./app');

var server=http.createServer(app);

server.listen(3000,function(){

console.log('server Listening on port 3000');

});

app.js 代碼如下:

var express=require('express');

var app=express();

app.use(function(req,res){

     console.log('firstMiddleware')

});

module.exports=app;

router.js代碼如下:

var express=require('express');

var router=express.Router();

router.use(function(req,res,next){

     console.log('firstMiddleware')

});

module.exports=router;

1、下面先對單箇中間件進行詳解:

        應用級中間件和路由級中間件用法相同(執行函數都是自己編寫),應用級中間件使用方式爲app.use([path,] function [, function...]) 和 app.METHOD([path,] function [, function...]);路由級中間件的使用方式爲router.use([path,] function [, function...]) 和 router.METHOD([path,] function [, function...]) 其中,METHOD 是需要處理的 HTTP 請求的方法,例如 GET, PUT, POST 等等,所有請求方法都要小寫,.use和.METHOD的兩種用法也是相同的,下面以app.use()爲例進行解析。

參數說明:

       path :爲訪問路徑格式爲 '/../..',可以省略,省略則所有請求都執行該中間件;

       function:爲執行函數,每個中間件的執行函數可以爲單個、多個、執行函數的數組,也可以是他們的組合,但至少得有一個執行函數;下面對他們分別介紹。

      ①單個執行函數:

         當前的app.js文件中的中間件即爲典型的單個執行函數;

      ②多個執行函數:

         現把app.js文件修改爲:

var express=require('express');

var app=express();

var f1=function(req,res,next){

console.log('firstMiddleware  f1')

     next();

};

varf2=function(req,res,next){

     console.log('firstMiddleware  f2')

    next();

};

var f3=function(req,res,next){

     console.log('firstMiddleware  f3')

};

app.use(f1,f2,f3);

module.exports=app;

執行結果爲:

firstMiddleware  f1

firstMiddleware  f2

firstMiddleware  f3

        此即爲典型的多個執行函數。

        其中app.use(f1,f2,f3)可以修改爲app.use(f1,[f2,f3])爲函數與函數數組的結合,修改爲app.use([f1,f2,f3])即爲函數數組的方式;

       當一箇中間件有多個執行函數時,前面的執行函數要調用next函數,不調用next函數,後面的函數將無法執行若該執行函數之前還未把res發出則會出現請求掛起,如:把f2 的 next()刪除,再運行發出請求後請求將掛起,若把f2的next()刪除後加上res.send('respose has sended!'); 則請求不再掛起但f3不會執行。由於路由中間件用法相同就不再詳解。

 

2、下面對多箇中間件之間的組合進行詳解:

       當有多箇中間件時,各個中間件以此與請求路徑進行匹配,匹配成功則運行,不成功跳過,所有一般按匹配範圍排列中間件,把匹配範圍大的中間件放到前面(所有請求都執行的中間件匹配範圍最大,所有一般都放到最前面)依次排列。

      現對app.js修改如下:

var express=require('express');

var app=express();

var f1=function(req,res,next){

console.log('firstMiddleware  f1');

next();

};

var f2=function(req,res,next){

     console.log('firstMiddleware  f2');

     next();

};

 

app.use(f1,f2);

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

     console.log('secondMiddleware');

res.set({

     'Content-Type':'text/plain',

     'Content-Length':'123',

     'ETag':'12345'

     })

     next();

})

app.use('/hello',function(req,res,next){

     console.log('hello middleware');

     res.send('response has sended!');

});

module.exports=app;

 

       一般一個請求所匹配的所有中間件的執行函數除最後一個執行函數外都要調用next,否則後面的執行函數或中間件將無法執行,若res還未發出請求將會掛起,(其後的中間件也無法執行,即前面中間件的每個執行函數都有調用next,否則將不會再往後執行),若當前函數沒有處理res 則會出現請求掛起,如把第二個中間件的next()刪除後運行。若前面的函數或中間件已經將res發出,則後面的函數或中間件將不能在對res的header進行設置,否則會報錯,如把app.js改爲:

var express=require('express');

var app=express();

var f1=function(req,res,next){

console.log('firstMiddleware  f1');

next();

};

var f2=function(req,res,next){

     console.log('firstMiddleware  f2');

     next();

};

 

app.use(f1,f2);

app.use('/hello',function(req,res,next){

     console.log('hello middleware');

     res.send('response has sended!');

     next();

});

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

     console.log('secondMiddleware');

res.set({

     'Content-Type':'text/plain',

     'Content-Length':'123',

     'ETag':'12345'

     })

})

module.exports=app;

當以上的代碼執行時,發送請求會出現res已經發送不能對res的header進行設置的錯誤。

---------------------------------------------------------------------------------------------------------------------

未完待續!

關於express中間件的詳細介紹請到:express中間件使用

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章