express中间件
# express中间件
业务流程得中间处理环节
当一个请求到达 Express
的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理
格式示例
let express = require('express')
let app = express()
const mw = function(req,res,next){
console.log('基本中间件函数')
next()
}
app.get('/',mw,function(req,res){
})
app.listen(3000)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
next()
函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由器
# 中间件类别
应用级别中间件 (app)
路由级别中间件(router)
错误级别的中间件
错误级别中间件的作用:专门用来捕获整个项目中发送的异常错误,从而防止项目异常崩溃的问题
app.get('/',function(req,res){
throw new Error('服务器内错误')
res.send('Home')
})
app.use(function(err,req,res,next){
res.send('Error'+err.message)
})
1
2
3
4
5
6
7
2
3
4
5
6
7
// 注意 ,错误级别的中间件必须写在路由之后
# 中间件作用
多个中间件之间,共享同一份 req
和 res
基于这样的特性,可以在上游的中间件中,统一为 req
和 res
对象添加自定义的属性或方法来供下游使用
示例
app.use((req,res,next)=>{
const time = Date.now()
req.startTime = time
next()
})
1
2
3
4
5
2
3
4
5
所有的路由处理函数都可以获取到 startTime 的值
# 全局中间件
使用 app.use(中间件函数)
,可以定义一个全局生效的中间件
同时也可以简化这个写法
app.use((req,res,next)=>{
next()
})
1
2
3
2
3
注意 多个全局中间件会根据代码顺序依次执行
# 局部中间件
app.get('URL',wm,function(req,res){
})
1
2
3
2
3
在路由函数中加入中间件处理函数,对当前路由生效的中间件
多个局部中间件
app.get('URL',wm1,wm2,wm3,function(req,res){
})
//or
app.get('URL',[wm1,wm2,wm3],function(req,res){
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 基本使用
const mw = function(req,res,next){
console.log('基本中间件函数')
next()
}
1
2
3
4
2
3
4
可以将这个中间件处理函数定义为全局生效的中间件
# express内置中间件
- express.static (快速托管静态资源的内置中间件)
- express.json (解析JSON格式的请求体数据)
- express.urlencoded (解析URL-encoded格式的请求数据)
app.use(express.json())
app.use(express.urlencoded({extended:false}))
1
2
2
# 自定义中间件
需求:手动模拟实现一个类似 express.urlencoded
这样的中间件,来解析 POST 提交到服务器的表单数据
定义中间件
监听
req
的data
事件监听
req
的end
事件(在中间件中,需要监听
req
对象的data
事件,来获取客户端发送到服务器的数据如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后,分批发送到服务器。所有
data
事件可能会被触发多次,每一次触发data
事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接)使用
querystring
的模块解析请求体数据将解析出来的数据挂载为
req.body
将自定义中间件封装为模块
let express = require('express')
const qs = require('querystring')
let app = express()
//1.
app.use(function(req,res,next){
let str = ''
//2.
req.on('data',(chunk)=>{
str += chunk
})
//3.
req.on('end',()=>{
//4.
const body = qs.parse(str)
//5.
req.body = body
next()
})
})
app.post('/user',(req,res)=>{
res.send(req.body)
})
app.listen(80)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
导出为模块
const qs = require('querystring')
const bodyParser = (req,res,next)=>{
let str = ''
//2.
req.on('data',(chunk)=>{
str += chunk
})
//3.
req.on('end',()=>{
//4.
const body = qs.parse(str)
//5.
req.body = body
next()
})
}
module.export = bodyParser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 注意事项
- 在路由之前注册中间件
- 可以连续调用多个中间件
- 不要忘记调用
next
函数 next
函数之后一般不再写额外代码
编辑 (opens new window)
上次更新: 2023/02/07, 14:51:48