1.中间件概念
所谓中间件,特指业务流程中间处理环节
2.全局生效中间件
// 导入需要的模块
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+` 版本中可用),用法同上 -
第三方的中间件
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()
})
})
|