首頁技術文章正文

Express中間件的調用流程和常規(guī)操作,5分鐘了解

更新時間:2022-10-13 來源:黑馬程序員 瀏覽量:

中間件(Middleware ),特指業(yè)務流程的中間處理環(huán)節(jié)。例如工廠要排放生產中產生的污水,就必須要先將污水凈化以達到排放標準你,處理污水的時候,經過的三個處理環(huán)節(jié),就可以叫做中間件。

1665643698803_中間件.png

Express 中間件的概念

Express 的中間件,本質上就是一個 function 處理函數, 中間件函數的形參列表中,必須包含 next 參數。而路由處理函數中只包含 req 和 resExpress ,中間件的格式如下:

express中間件

next 函數是實現(xiàn)多個中間件連續(xù)調用的關鍵,它表示把流轉關系轉交給下一個中間件或路由。Express中間件從到響應的流程如下:

1665644711078_5.png
下面我們來看Express中間件的幾種常規(guī)操作。

中間件常規(guī)操作

1. 定義中間件函數

可以通過如下的方式,定義一個最簡單的中間件函數:

//常量mw所指向的,就是一個中間件函數
const mw = function (req, res, next){
  console.log('這是一個最簡單的中間件函數')
  //注意:在當前中間件的業(yè)務處理完畢后,必須調用 next()函數
  //表示把流轉關系轉交給下一個中間件或路由
  next()
}


2. 全局生效的中間件

客戶端發(fā)起的任何請求,到達服務器之后,都會觸發(fā)的中間件,叫做全局生效的中間件。 通過調用app.use(中間件函數),即可定義一個全局生效的中間件,全局生效中間件的示例代碼如下:

//常量mw所指向的,就是一個中間件函數
const mw = function (req, res, next) {
console.log('這是一個最簡單的中間件函數’)
  next()
}

//全局生效的中間件
app.use(mw)

3. 定義全局中間件的簡化形式
定義全局中間件的簡化形式可以參考如下代碼:

//全局生效的中間件
app.use(function (req, res, next) {
  console.log(’這是一個最簡單的中間件函數’)
  next()
})

4. 中間件的作用

多個中間件之間,共享同一份req和res?;谶@樣的特性,我們可以在上游的中間件中,統(tǒng)一為req 或res 對象添加自定義的屬性或方法,供下游的中間件或路由進行使用。

1665645930390_6.png

5. 定義多個全局中間件

可以使用app.use() 連續(xù)定義多個全局中間件??蛻舳苏埱蟮竭_服務器之后,會按照中間件定義的先后順序依次進行調用,示例代碼如下:

app.use(function(req,res,next){//第1個全局中間件
  console.log('調用了第1個全局中間件')
next()
})
app.use(function(req,res,next){//第2個全局中間件
console.log('調用了第2個全局中間件')
next()
1})
app.get('/user',(req,res)=>{//請求這個路由,會依次觸發(fā)上述兩個全局中間件
res.send('Home page.')
})

6. 局部生效的中間件

不使用app.use() 定義的中間件,叫做局部生效的中間件,示例代碼如下:

//定義中間件函數mw1
const mw1 = function(req, res, next) (
cosole.log('這是中間件函數')
  next()
}
//mN1 
這個中間件只在“當前路由中生效”,這種用法屬于“局部生效的中間件”
app.get('/',mwi,function(req,res){
res.send('Home page.')
})
//mw1這個中間件不會影響下面這個路由!+
app.get('/user', 
function(req, res) { res.send('User page.') })

7. 定義多個局部中間件

可以在路由中,通過如下兩種等價的方式,使用多個局部中間件:

//以下兩種寫法是“完全等價“的,可根據自己的喜好,選擇任意一種方式進行使用
apg.get('/',mw1,mw2,(req,res)=>{res.send('Home page.')})
app.get('/',[mw1,mw2],(req,res)=>{ res.send('Home page.') })

注意:一定要在路由之前注冊中間件,客戶端發(fā)送過來的請求,可以連續(xù)調用多個中間件進行處理。執(zhí)行完中間件的業(yè)務代碼之后,不要忘記調用next() 函數。為了防止代碼邏輯混亂,調用next() 函數后不要再寫額外的代碼。連續(xù)調用多個中間件時,多個中間件之間,共享req 和res 對象。

中間件的分類

為了方便大家理解和記憶中間件的使用,Express 官方把常見的中間件用法,分成了5 大類,分別是:

①應用級別的中間件

②路由級別的中間件

③錯誤級別的中間件

④Express 內置的中間件

⑤第三方的中間件

1. 應用級別的中間件

通過app.use() 或app.get() 或app.post() ,綁定到app 實例上的中間件,叫做應用級別的中間件,代碼示例如下:

//應用級別的中間件(全局中間件)
app.use((req,res,next)=>{
  next()
})

//應用級別的中間件(局部中間件)
app.get('/',mwi,(req, res) =>{
  res.send('Home page.')
})

2. 路由級別的中間件

綁定到express.Router() 實例上的中間件,叫做路由級別的中間件。它的用法和應用級別中間件沒有任何區(qū)別。只不過,應用級別中間件是綁定到app 實例上,路由級別中間件綁定到router 實例上,代碼示例如下:

var app = express()
var router = express.Router(

//路由級別的中間件
router.use(function (req, res, next) (
  console.log('Time:', Date.now())
  next()
})

app.use('/', router)

3. 錯誤級別的中間件

錯誤級別中間件的作用:專門用來捕獲整個項目中發(fā)生的異常錯誤,從而防止項目異常崩潰的問題。

格式:錯誤級別中間件的function 處理函數中,必須有4 個形參,形參順序從前到后,分別是(err, req, res, next)。

app.get('/', function (req, res){             // 1.路由
  throw new 
Error('服務器內部發(fā)生了錯誤!') // 1.1拋出一個自定義的錯誤
  res.send('Home 
Page.')
})
app.use(function(err,req,res,next){          // 2.錯誤級別的中間件
console.log('發(fā)生了錯誤:'+err.message)    //2.1在服務器打印錯誤消息
  res.send('Error!'+ 
err.message)            //2.2向客戶端響應錯誤相關的內容
})

注意:錯誤級別的中間件,必須注冊在所有路由之后!

4. Express內置的中間件

自Express 4.16.0 版本開始,Express 內置了3 個常用的中間件,極大的提高了Express 項目的開發(fā)效率和體驗:

①express.static快速托管靜態(tài)資源的內置中間件,例如:HTML 文件、圖片、CSS 樣式等(無兼容性)

②express.json解析JSON 格式的請求體數據(有兼容性,僅在4.16.0+ 版本中可用)

③express.urlencoded解析URL-encoded 格式的請求體數據(有兼容性,僅在4.16.0+ 版本中可用)

//配置解析 application/json 格式數據的內置中間件
app.use(express.json())
//配置解析 application/x-ww-form-urlencoded 格式數據的內置中間件
app.us(express.urlencoded({ extended:false }))

5. 第三方的中間件

非Express 官方內置的,而是由第三方開發(fā)出來的中間件,叫做第三方中間件。在項目中,大家可以按需下載并配置第三方中間件,從而提高項目的開發(fā)效率。

例如:在express@4.16.0 之前的版本中,經常使用body-parser 這個第三方中間件,來解析請求體數據。使用步驟如下:

①運行npm install body-parser安裝中間件

②使用require導入中間件

③調用app.use() 注冊并使用中間件

注意:Express 內置的express.urlencoded中間件,就是基于body-parser 這個第三方中間件進一步封裝出來的。


分享到:
在線咨詢 我要報名
和我們在線交談!