對於Node中Express框架的中間件概念的感知

中間件是什麼呢?javascript

中間件就是客戶端http請求發起傳送到服務器和服務器返回響應之間的一些處理函數。java

 

爲何要使用中間件?express

經過中間件,能夠 對數據進行操做使得咱們能方便地操做請求數據編寫服務器響應。如body-parse中間件對post請求的參數進行處理讓咱們能夠經過res.body快速獲取請求參數,express-session中間件可讓咱們對數據進行保存,express.static是express內置中間件,可讓咱們快速處理靜態資源,express.Router路由中間件等等
 
中間件如何使用?
Express中,對中間件進行了幾種分類:
1.不關心請求路徑和請求方法的中間件,經過app.use函數實現
app.use(function(req,res,next){})
客戶端發起的任意請求都會通過這個中間件函數進行處理
next指下一個知足路徑條件的中間件,若是有執行next,那麼這個中間件執行完後就會執行下一個知足條件的中間件,若是沒有next,就會忽略後面全部中間件
 
如下面代碼爲例(設服務器ip爲127.0.0.1,後面全部例子都以該ip爲例)
var express = require('express')
var app = express()

app.use(function(req,res) {
    res.end('404 NOT FOUND')
}

app.listen(3000,function(){
    console.log('running...');
}

全部對該服務器的請求最終都會返回404 NOT FOUND,不管是路徑是什麼服務器

2.關心請求路徑的中間件,經過app.use函數實現
app.use(路徑,function(req,res,next){})
客戶端發起的以 第一個參數開頭的路徑纔會進入該中間件
 
如下代碼爲例
var express  = require('express')
var app = express()

app.use('/public',function(req,res,next) {
    res.end('you are public');
}

app.listen(3000,function(){
    console.log('running...')
}

 只要客戶端訪問該服務器的地址是以public開頭(即127.0.0.1:3000/public/xxx),那麼就會返回you are public 字符串session

 

3.嚴格匹配路徑的中間件,經過app.get/app.post等實現
也就是咱們所說的服務器路由
app.get(路徑,函數)
app.post(路徑,函數)
只有嚴格匹配請求方式和請求路徑的請求才會進入該中間件
 
如下面代碼爲例
var express = require('express')
var app = express()

// 中間件1 app.get('/get/puclic',function(req,res){ res.end('get!'); } // 中間件2 app.post('/post/public',function(req,res) { res.end('post!'); } app.listen(3000,function(){ console.log('running...'); }

 客戶端只有經過get方式訪問127.0.0.1:3000/get/public時纔會進入中間件1,只有經過post方式訪問127.0.0.1:3000/post/public時纔會進入中間件2,只有這二者徹底匹配纔會進入對應的中間件app

 

中間件的執行機制:
1.中間件的第一次執行是同步的,當一個請求發出到達服務器後,則按照順序匹配全部中間件,當找到一個匹配時,則進入該中間件
2.若是該中間件最後沒有執行next函數,則該請求在此中間件終止,再也不進入後面的中間件;若是有,則會直接進入後面匹配的中間件中(此時再也不是按順序!)
3.重複1-2步
 
若是把客戶端發起請求和服務器發出響應比做自來水的進入水庫和輸出水庫,那麼中間件就是水庫裏對水分別進行過濾沉澱消毒的各個小廠房,而中間件的函數的next參數就至關於每一個小廠房的門,只有這個門打開了,處理完的請求的數據才能繼續向後面的中間件發送,直至響應發出。
 
 

 

如下面的代碼爲例進一步說明中間件的執行順序函數

var express = require('express');

var app = express()

//中間件1 app.use(function(req,res) { console.log('非嚴格'); })
//中間件2 app.use('/public',function(req,res,next) { console.log('半嚴格');
    next(); })
//中間件3 app.get('/public',function(req,res) { console.log('嚴格 get'); })
//中間件4 app.post('/public',function(req,res) { console.log('嚴格 post'); })

//中間件5
app.get('/public',function(req,res) { console.log('嚴格 get'); })
app.listen(3000,function() { console.log('running...') })

 此時客戶端訪問/public,那麼首先會進入中間件1,由於有執行next函數,因此直接尋找後面可以匹配的中間件,進入中間件2,中間有執行next函數,因此進入中間件3,可是中間件3沒有next函數,因此再也不執行,因此輸出的語句是‘非嚴格’ '半嚴格' '嚴格 get'post

 

若是是下面代碼,請求/public後結果又是怎樣呢?ui

var express = require('express');

var app = express()


app.use('/img',function(req,res) {
	console.log('半嚴格');
})

app.get('/public',function(req,res) {
	console.log('嚴格 get');
})

app.post('/public',function(req,res) {
	console.log('嚴格 post');
})

app.listen(3000,function() { console.log('running...') })

 結果是輸出'嚴格 get',請求到達服務器後,從上往下逐漸匹配,匹配到第二個中間件,進入執行,可是該中間件沒有執行next函數,因此終止spa

 

綜上所述,咱們能夠知道,第三方中間件的安裝執行是有講究的

對於一些封裝請求數據方便咱們操做以及處理靜態資源的中間件咱們應該放在路由中間件(即有發出服務器響應的中間件)以前編寫,不然在編寫路由時就沒法使用封裝好的數據。而對於返回404頁面的路由能夠放在全部中間件後面,這樣沒法找到的頁面則會自動匹配到最後一個返回404頁面
 
中間件的使用是靈活多變的,本文章只是簡單概述其概念及其執行機制,更多技巧仍需讀者自行體會
相關文章
相關標籤/搜索