Express 是一個自身功能 極簡,完全是由路由和中間件構(gòu)成的一個web開發(fā)框架,從本質(zhì)上來說,一個Express 應用就是在調(diào)用各種中間件。
中間件就是匹配路由之前或者匹配路由完成時所作的一系列的操作,叫做中間件。
- 中間件的結(jié)構(gòu):
app.use([path, ] callback [, callback ...])
// 1. path是可選的參數(shù),為路由的url, 如果省略將匹配到所有路徑
// 2. callback中間件函數(shù),當路由匹配成功執(zhí)行函數(shù),函數(shù)將接受三個參數(shù)(
// req: HTTP請求對象, res: HTTP響應對象, next: 處理完后交給下一個路由,若不調(diào)用則處理到此為止,不會繼續(xù)后面的操作。)
- 代碼示例:
// 中間件
const express = require('express');
const app = express();
// 創(chuàng)建第一個中間件
app.use((req, res, next) => {
console.log(111);
})
// 創(chuàng)建第二個中間件
app.use((req, res, next) => {
console.log(222);
})
app.listen(3000, () => console.log('Server port 3000 at start....'));
當不加上路徑的時候會匹配所有路由路徑,但是如果不加上尾函數(shù)next那么會無法進入到下一個中間件,也就是說網(wǎng)頁會出現(xiàn)停滯狀態(tài)(一直處于加載狀態(tài))。
-
尾函數(shù):
如果在中間件里不調(diào)用next函數(shù),整個請求響應的流程會中斷,不會繼續(xù)往下執(zhí)行。
// 中間件
const express = require('express');
const app = express();
// 創(chuàng)建第一個中間件
app.use((req, res, next) => {
console.log(111);
next()
})
// 創(chuàng)建第二個中間件
app.use((req, res, next) => {
console.log(222);
})
app.listen(3000, () => console.log('Server port 3000 at start....'));
// 111
// 222
-
洋蔥模型:
中間件的洋蔥模型在于,執(zhí)行到尾函數(shù),就去執(zhí)行下一個中間件,也就是說最先進去的最后出來。
圖1.png 示例代碼:
// 中間件
const express = require('express');
const app = express();
// 創(chuàng)建第一個中間件
app.use((req, res, next) => {
console.log('middleware_1: 111');
next()
console.log('middleware_1: 222');
})
// 創(chuàng)建第二個中間件
app.use((req, res, next) => {
console.log('middleware_2: aaa');
next();
console.log('middleware_2: bbb');
});
// 創(chuàng)建第三個中間件
app.use((req, res, next) => {
console.log('middleware_3: 布局');
next();
console.log('middleware_3: 測試');
});
// middleware_1: 111
// middleware_2: aaa
// middleware_3: 布局
// middleware_3: 測試
// middleware_2: bbb
// middleware_1: 222
app.listen(3000, () => console.log('Server port 3000 at start....'));
-
對不同路由路徑設置中間件:
這一塊需要注意的是,該路由匹配模式并非是完整的路徑匹配,而是模糊路徑匹配。
// 中間件
const express = require('express');
const app = express();
app.use('/student', (req, res, next) => {
res.send('<h1>學生界面</h1>')
next();
})
app.use('/', (req, res, next) => {
res.send(`<h1>首頁界面</h1>`);
})
app.listen(3000, () => console.log('Server port 3000 at start....'));
-
多個回調(diào)函數(shù)的中間件:
在寫多個回調(diào)函數(shù)的中間件時,也需要添加next()尾函數(shù),next() 指的是進入下一個中間件或者是進入當前中間件的下一個回調(diào)函數(shù)!
// 中間件
const express = require('express');
const app = express();
// 多個回調(diào)函數(shù)的中間件
// next() 指的是進入下一個中間件或者是進入當前中間件的下一個回調(diào)函數(shù)!
app.use((req, res, next) => {
console.log(111);
next();
console.log(1110111);
}, (req, res, next) => {
console.log(222);
next();
console.log(2220222);
}, (req, res, next) => {
console.log(333);
next();
console.log(3330333);
})
app.use((req, res, next) => {
console.log(444);
next();
console.log(4440444);
});
// 111
// 222
// 333
// 444
// 4440444
// 3330333
// 2220222
// 1110111
app.listen(3000, () => console.log('Server port 3000 at start....'));
