目录
1. 中间件介绍
1.1 中间件的概念
中间件(Middleware), 特指业务流程的中间处理环解。
1.2 现实生活中的例子
在处理污水的时候,一般都要经过三个处理环节,从而保证处理后的废水,达到排放标准。
图示:
处理污水的中间三个处理环节,就可以叫做中间件
1.3 中间件的调用流程
当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
图示:
1.4 中间件格式
Express 的中间件,本质上就是一个 function 处理函数,Express 中间件的格式如下:
注意:中间件函数的形参列表中,必须包含 next 参数。而路由处理函数中只包含 req 和 res。
1.5 next 函数的作用
next 函数是实现多个中间件连续调用的关键,他表示把流转关系转交给下个一中间件或路由。
2. Express 中间件初体验
2.1 定义中间件函数
可以通过如下方式定义一最简单的中间件函数:
// 定义一个简单的中间件函数
const mw = (req, res, next) => {
console.log('我是一个中间键函数')
// 把流转关系交给下一个中间件或路由
next()
}
注意:在当前中件的业务处理完毕后,必须调用 next() 函数,表示把流转关系转交给下一个中间件或路由
注意:中间件函数与普通函数最大的区别就是参数,参数一:req,参数二:res,参数三:next
2.2 全局生效的中间件
客户端发起的任何请求,到达服务器之后,都会触发中间件,叫做全局生效的中间件,客户端通过调用 app.use(中间件函数),即可定义一个全局生效的中间件,示例代码如下:
app.use((req, res, next) => {
console.log('我是全局中间件')
next()
})
2.3 中间件的作用
多个中间件之间,共享一份 req 和 res。基于这样的特性,我们可以在上游中间件中,统一为 req 或 res 对象添加 自定义 的 属性 或 方法,供下游的中间件或路由进行使用
图示:
代码示例:
// 注册全局中间件
app.use((req, res, next) => {
// 获取当前时间
const time = Date.now()
// 将当前事件存入 res 中
req.startTime = time
console.log('我是全局中间件一')
next()
})
app.get('/', (req, res) => {
res.send('Hello, 中间件1' + req.startTime)
})
响应结果:
2.4 定义多个全局中间件
可以使用 app.use() 连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用。
2.5 局部生效的中间件
不适用 app.use() 定义的中间件,叫做局部生效的中间件,示例代码如下:
// 定义一个中间件函数
const mw = function(req, res, next) {
console.log('调用了中间件函数')
next()
}
app.get('/', mw, (req, res) => {
res.send('Hello Get')
})
注意:mw 这个中间件只在“当前路由中生效”,这种用法属于“局部生效的中间件”
2.6 定义多个局部中间件
可以在路由中,通过如下两种等价的方式,使用多个局部中间件:
以下两种方法是“完全等价”的,可根据自己的喜好,选择任意一种方式进行使用
// 其中 mw1 mw2 均为中间件函数
app.get('/', mw1, mw2, (req, res) => {res.send('Home page')})
app.get('/', [mw1, mw2], (req, res) => {res.send('Home page')})
注意:第一个参数,永远是请求的 URL 地址,最后一个参数永远是路由对应的处理函数,在中间可以写任意多个局部的中间件,他们的顺序是从前到后的,先是 mw1,后是 mw2。
3. 中间间的在5个注意事项
1. 一定要在路由之前注册中间件,否则中间件将不会生效,错误级别的中间件例外,错误级别的中间件必须放在路由注册之后
2. 客户端发送过来的请求,可以连续调用多个中间件进行处理
3. 执行完中间件的业务代码之后,不要忘记调用 next() 函数
4. 为了防止代码逻辑混乱,调用 next() 函数后不要写额外的代码
5. 连续调用多个中间件时,多个中间件之间,共享 req 和 res 对象