1.中间件概念
所谓中间件,特指业务流程中间处理环节
2.全局生效中间件
-
客户端发起的的任何请求,到达服务器之后,都会触发的的中间件
-
通过调用 app.use(中间件函数),即可定一个全局中间件
// 导入需要的模块
const express = require('express')
const app = express()
// // 定义一个简单中间件函数
// const kw = (req,res,next)=> {
// console.log('这是最简单中间件');
// // 把流转关系传给下一个中间件或者路由
// next()
// }
// // 全局生效中间件
// app.use(kw)
// 简化
// 第一个中间件
app.use((req,res,next)=>{
console.log('这是最简单中间件');
next()
})
// 第二个中间件
app.use((req,res,next)=>{
console.log('这是最简单中间件3333');
next()
})
app.get('/',(req,res)=>{
console.log('调用了/这个路由');
res.send('fdff')
})
app.listen(3000,()=>{
console.log('完成');
})
3.中间件作用
多个中间件之间,共享一份 req , res, 基于这样特性,我们可以在上游中间件中,统一为 req, res对象添加自定义属性方法,供下游中间件或路由器进行使用
4.局部生效的中间件
- 不使用 app.use() 定义的中间件,叫做局部中间件
const express = require('express')
const app = express()
// 中间件
const mv1 = (req,res,next) => {
console.log('这是中间件数');
next()
}
app.get('/',(req,res)=>{
res.send('ggjg')
})
app.get('/user',mv1,(req,res)=>{
res.send('ffddf')
})
app.listen(3000,()=>{
console.log('完成');
})
5.中间件注意事项
-
一定要在路由之前注册中间件
-
客户端发送过来的请求,可以连续调用多个中间件进行处理
-
执行完中间件的业务代码之后,不要忘记调用
next()
函数 -
为了防止代码逻辑混乱,调用
next()
函数后不要再写额外的代码 -
连续调用多个中间件时,多个中间件之间,共享
req
和res
对象
6.中间件分类
-
应用级别的中间件
- 通过
app.use()
或app.get()
或app.post()
,绑定到app
实例上的中间件,叫做应用级别的中间件
- 通过
-
路由级别的中间件
- 绑定到
express.Router()
实例上的中间件,叫做路由级别的中间件
- 绑定到
-
错误级别的中间件
- 注意:错误级别中间件必须注册在所有路由之后
const express = require('express') const app = express() app.get('/',(req,res)=>{ throw new Error('服务器内部发生错误') res.send('fsaf') }) // 错误级别中间件,放在所有路由最后面 app.use((err,req,res,next)=>{ console.log('发生了错误'+err.message); res.send(err.message) }) app.listen(3000,()=>{ console.log('完成'); })
-
Express 内置的中间件
- express.static
快速托管静态资源的内置中间件,例如: HTML 文件、图片、
CSS` 样式等(无兼容性) - express.json
解析
JSON格式的请求体数据(**有兼容性**,仅在
4.16.0+` 版本中可用)
const express = require('express') const app = express() app.use(express.json()) app.post('/user',(req,res)=>{ // req.body接收客户端请求体 res.send(req.body) }) app.listen(3000,()=>{ console.log('完成'); })
- express.urlencoded
解析
URL-encoded格式的请求体数据(**有兼容性**,仅在
4.16.0+` 版本中可用),用法同上
- express.static
-
第三方的中间件
7.自定义中间件
- 自己手动模拟一个类似于
express.urlencoded
这样的中间件
// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()
// 4. 导入 Node 内置模块 querystring
const qs = require('querystring')
// 解析表单数据的中间件
app.use((req,res,next)=>{
// 定义中间价具体的业务逻辑
// 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
let str = ''
// 2. 监听 req 的 data 事件
req.on('data',rem =>{
str+=rem
})
// 3. 监听 req 的 end 事件
req.on('end',()=>{
// 5. 调用 qs.parse() 方法,将查询字符串解析成对象
const arr = qs.parse(str)
req.body=arr
next()
})
})
app.post('/user',(req,res)=>{
// 6. 将解析出来的数据对象挂载为 req.body 属性
res.send(req.body)
})
// 调用 app.listen方法,指定端口号并启动 web 服务器
app.listen(3000,()=>{
console.log('完成');
})
-
在上面基础上封装
服务器
// 导入 express 模块 const express = require('express') // 创建 express 的服务器实例 const app = express() // 4. 导入 Node 内置模块 querystring // 导入中间件模块 const arr = require('./封装中间件') // 全局中间件 app.use(arr) app.post('/user', (req, res) => { // 6. 将解析出来的数据对象挂载为 req.body 属性 res.send(req.body) }) // 调用 app.listen方法,指定端口号并启动 web 服务器 app.listen(3000, () => { console.log('完成'); })
中间件
const qs = require('querystring')
// 解析表单数据的中间件
module.exports=((req, res, next) => {
// 定义中间价具体的业务逻辑
// 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
let str = ''
// 2. 监听 req 的 data 事件
req.on('data', rem => {
str += rem
})
// 3. 监听 req 的 end 事件
req.on('end', () => {
// 5. 调用 qs.parse() 方法,将查询字符串解析成对象
const arr = qs.parse(str)
req.body = arr
next()
})
})