一、中间件
中间件(Middleware ),特指业务流程的中间处理环节
二、Express 中间件的调用流程
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c4fad0271d4c824e3602e8bdd248670c.png)
当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理。
三 、 next 函数的作用
next 函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/f87f26eafa5e0ca7742fe98f2f06ad32.png)
const express = require('express')
const app = express()
const mw = function (req, res, next) {
console.log('这是最简单的中间件函数')
next()
}
app.use(mw)
app.get('/', (req, res) => {
console.log('调用了 / 这个路由')
res.send('Home page.')
})
app.get('/user', (req, res) => {
console.log('调用了 /user 这个路由')
res.send('User page.')
})
app.listen(80, () => {
console.log('http://127.0.0.1')
})
四、中间件的作用
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8ff5bd5e0516c14e0cb968d3e642922f.png)
多个中间件之间,共享同一份 req 和 res。基于这样的特性,我们可以在上游的中间件中,统一为 req 或 res 对象添
加自定义的属性或方法,供下游的中间件或路由进行使用。
const express = require('express')
const app = express()
app.use((req, res, next) => {
const time = Date.now()
req.startTime = time
next()
})
app.get('/', (req, res) => {
res.send('Home page.' + req.startTime)
})
app.get('/user', (req, res) => {
res.send('User page.' + req.startTime)
})
app.listen(80, () => {
console.log('http://127.0.0.1')
})
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/762da3ebcbde5c6f05a4ebc66077e79d.png)
五、定义多个全局中间件
可以使用 app.use() 连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行
调用
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('调用了第1个全局中间件')
next()
})
app.use((req, res, next) => {
console.log('调用了第2个全局中间件')
next()
})
app.get('/user', (req, res) => {
res.send('User page.')
})
app.listen(80, () => {
console.log('http://127.0.0.1')
})
六、局部生效的中间件
不使用 app.use() 定义的中间件,叫做局部生效的中间件
const express = require('express')
const app = express()
const mw1 = (req, res, next) => {
console.log('调用了局部生效的中间件')
next()
}
app.get('/', mw1, (req, res) => {
res.send('Home page.')
})
app.get('/user', (req, res) => {
res.send('User page.')
})
app.listen(80, function () {
console.log('Express server running at http://127.0.0.1')
})
七、定义多个局部中间件
依旧存在顺序性
const express = require('express')
const app = express()
const mw1 = (req, res, next) => {
console.log('调用了第一个局部生效的中间件')
next()
}
const mw2 = (req, res, next) => {
console.log('调用了第二个局部生效的中间件')
next()
}
app.get('/', [mw1, mw2], (req, res) => {
res.send('Home page.')
})
app.get('/user', (req, res) => {
res.send('User page.')
})
app.listen(80, function () {
console.log('Express server running at http://127.0.0.1')
})
八、5个使用注意事项
一定要在路由之前注册中间件
客户端发送过来的请求,可以连续调用多个中间件进行处理
执行完中间件的业务代码之后,不要忘记调用 next() 函数
为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
连续调用多个中间件时,多个中间件之间,共享 req 和 res 对象