背景
中间件的应用十分广泛。
场景1:
我们需要记录每个接口调用时间时,就可以使用中间件函数。使用中间件函数后,在调用每个接口时,在不修改之前接口代码的基础上,可以自动打印对应的时间。
场景2
路由也是中间件
:只不过路由会限制对中间件的规则有限制。
常用中间件
- 打印接口调用时间
- 打印接口调用ip
- 打印接口耗时
app.use(async (req, res, next)=>{
let startTime = Date.now();
console.log("ip:" + req.ip + "------- interface:" + req.originalUrl + "----- time:" + currentTime)
// 把流转关系转交给下一个中间件或者路由
next()
let endTime = Date.now()
console.log(req.originalUrl + "-------- 执行时间:" + (endTime - startTime)/1000 + "s")
})
中间件
Express中间件和AOP面向切面编程是一个意思,不需要修改自己的代码,以此来扩展或者处理一些功能。
将日志记录,性能统计,安全控制,事务处理, 异常处理等代码从业务逻辑代码 中划分出来,通过对这些行为的分离,我们希望望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业上务逻辑的代码。
- 当一个请求到达Express的服务器后,可以连续调用多个中间件,从而对这次请求进行预处理。
- 中间件函数的形参列表中,必须包含next参数。而路由处理函数中只能包括req以及res。
- next()函数是实现多个中间件连续调用的关键,他表示把流转关系交给下一个中间件或路由。
- 多个中间件,共用一个req、res。
- 请求到来之后按照代码从上到下的顺序进行匹配,因此中间件需要在路由之前声明。
中间件可实现功能
1、执行任何代码
2、修改request或者response响应对象
3、结束请求相应周期
4、调用下一个中间件
如果从路由器中间件堆栈跳过其余中间件功能,请调用next('route')
将控制权传递给下一个路由。
注意:next('route')
仅在app.METHOD()
或router.METHOD()
函数加载的中间件函数中有效。
中间件的使用
const express = require("express");
const app = express()
// 定义一个简单的中间件 常量mw所指
const mw = function (req, res, next) {
console.log("这种最简单的中间件函数")
// 把流转关系转交给下一个中间件或者路由
next()
}
app.use(mw)
app.get('/',(req, res)=>{
console.log('Home page')
res.send("Home page")
})
app.get('/user',(req, res)=>{
console.log('user page')
res.send("user page")
})
app.listen(8080,()=>{
console.log("express start on 8080")
})
请求结果:
这种最简单的中间件函数
Home page
中间件的简化生成
中间件的调用可以这样简化:
const express = require("express");
const app = express()
// 定义全局中间件的简化形式
app.use((req, res, next)=>{
console.log("简化的全局中间件...")
next()
})
app.get('/',(req, res)=>{
console.log('Home page')
res.send("Home page")
})
app.get('/user',(req, res)=>{
console.log('user page')
res.send("user page")
})
app.listen(8080,()=>{
console.log("express start on 8080"