聲明:轉(zhuǎn)載請(qǐng)注意出處
技術(shù)交流:
微信公眾號(hào):北piao青年
EMAIL: hoojiaxin@hotmail.com
中間件是在接收到請(qǐng)求和發(fā)送響應(yīng)中間的一系列操作茂腥。事實(shí)上,express是一個(gè)路由和中間件的web框架懦趋,Express 應(yīng)用程序基本上是一系列中間件函數(shù)的調(diào)用楣铁。
中間件函數(shù)可以執(zhí)行以下任務(wù):
- 執(zhí)行任何代碼锉走。
- 對(duì)請(qǐng)求和響應(yīng)對(duì)象進(jìn)行更改。
- 結(jié)束請(qǐng)求/響應(yīng)循環(huán)鸳谜。
- 調(diào)用堆棧中的下一個(gè)中間件函數(shù)。
中間件也分為應(yīng)用層中間件式廷、路由中間件咐扭、內(nèi)置中間件、錯(cuò)誤處理中間件和第三方中間件滑废。
一蝗肪、應(yīng)用層中間件
應(yīng)用級(jí)別中間件綁定到app對(duì)象上,使用app.use和app.METHOD()(METHOD:需要處理http請(qǐng)求的方法蠕趁,例如GET薛闪、PUT、POST)
var express = require("express");
var app = express();
//匹配路由之前的操作
app.use(function(req,res,next()){
console.log("訪問之前");
});
app.get("/",function(req,res){
res.send("主頁");
});
app.listen(8080);
這時(shí)我們發(fā)送http://localhost:8080/請(qǐng)求妻导,地址一直在加載逛绵,但命令行里顯示了“訪問之前”,因?yàn)槲覀儾]有調(diào)用res對(duì)象的任何方法倔韭,如果想要得到字符串“主頁”的響應(yīng)內(nèi)容术浪,下面代碼會(huì)如你所愿。
var express=require("express");
var app=express();
//匹配路由之前的操作
app.use(function(req,res,next){
console.log("訪問之前");
//此處調(diào)用了next()方法寿酌,則程序才會(huì)往下執(zhí)行app.get處理請(qǐng)求并響應(yīng)字符串“主頁”
next();
});
app.get("/",function(req,res){
res.send("主頁");
});
app.listen(8080);
下面代碼是簡化版的寫法
var express=require("express");
var app=express();
app.use(function(req,res,next){
console.log("訪問之前");
next();
},function(req,res){
res.send("主頁");
});
app.listen(8080);
因此胰苏,在進(jìn)行路由匹配之前執(zhí)行某些程序處理,再繼續(xù)向下執(zhí)行匹配的路由函數(shù)醇疼,那么應(yīng)用層中間件無疑是好的選擇硕并。
二、路由中間件
路由級(jí)中間件和應(yīng)用級(jí)中間件類似秧荆,只不過他需要綁定express.Router();
var router = express.Router()
在匹配路由時(shí)倔毙,我們使用 router.use() 或 router.METHOD()(METHOD:需要處理http請(qǐng)求的方法,例如GET乙濒、PUT陕赃、POST)卵蛉,結(jié)合多次callback可用于用戶登錄及用戶狀態(tài)檢測。
var express = require("express");
var app = express();
var router=express.Router();
router.use("/",function(req,res,next){
console.log("匹配前");
next();
});
router.use("/user",function(req,res,next){
console.log("匹配地址:",req.originalUrl);
next();
},function(req,res){
res.send("用戶登錄");
});
app.use("/",router);
app.listen(8080);
總之在檢測用戶登錄狀態(tài)和權(quán)限判斷么库、引導(dǎo)用戶應(yīng)該訪問哪個(gè)頁面時(shí)傻丝,路由中間件是不錯(cuò)的選擇。
三诉儒、錯(cuò)誤處理中間件
顧名思義葡缰,它是指當(dāng)我們匹配不到路由時(shí)所執(zhí)行的操作。錯(cuò)誤處理中間件和其他中間件基本一樣忱反,只不過其需要開發(fā)者提供4個(gè)自變量參數(shù)泛释。
app.use((err, req, res, next) => {
res.sendStatus(err.httpStatusCode).json(err);
});
一般情況下,我們把錯(cuò)誤處理放在最下面缭受,這樣我們即可對(duì)錯(cuò)誤進(jìn)行集中處理胁澳。
var express = require("express");
var app = express();
app.get("/login",function(req,res,next){
if(req.query.username == 'david' && req.query.password == 123456){
res.send("主頁");
}else{
const err=new Error("用戶名或密碼錯(cuò)誤");
next(err);//直接調(diào)用app.use(function(err, req, res, next){})
}
});
//如果前面沒有匹配的請(qǐng)求,則會(huì)執(zhí)行此函數(shù)
app.use(function(req, res, next) {
next(404);
});
app.use(function(err, req, res, next) {
if(err === 404){
res.status(404).send("未找到指定頁面");
}else{
res.status(500).send(err.message);
}
});
四米者、內(nèi)置中間件
從版本4.x開始韭畸,Express不再依賴Content,也就是說Express以前的內(nèi)置中間件作為單獨(dú)模塊蔓搞,express.static是Express的唯一內(nèi)置中間件胰丁。
express.static(root, [options]);
通過express.static我們可以指定要加載的靜態(tài)資源
app.use(express.static(path.join(__dirname, 'public')));
image.png

五、第三方中間件
如body-parser喂分,采用引入外部模塊的方式來獲得更多的應(yīng)用操作锦庸。如cookie和session。
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
app.use(cookieParser());
在實(shí)際項(xiàng)目中蒲祈,中間件都是必不可少的甘萧,所以熟悉使用各種中間件可以加快項(xiàng)目的開發(fā)效率。