Express 中间件

中间件的概念
中间件(Middleware ),特指 业务流程 中间处理环节
Express 中间件的 调用流程
当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行 预处理
Express 中间件_第1张图片

 Express 中间件的格式

Express 的中间件, 本质 上就是一个 function 处理函数
注意:中间件函数的形参列表中, 必须包含 next 参数 。而路由处理函数中只包含 req 和 res。
next 函数的作用
next 函数 是实现 多个中间件连续调用 的关键,它表示把流转关系 转交 给下一个 中间件 路由
Express 中间件_第2张图片

 定义中间件函数

// 定义一个简单的中间件函数
const mw = (req, res, next) => {
    console.log('这是一个简单的中间件函数');
    // 把流转关系,转交给下一个中间件或者路由
    next()
}
全局生效 的中间件
客户端发起的 任何请求 ,到达服务器之后, 都会触发的中间件 ,叫做全局生效的中间件。
通过调用 app.use( 中间件函数 ) ,即可定义一个 全局生效 的中间件
// 定义一个简单的中间件函数
const mw = (req, res, next) => {
    console.log('这是一个简单的中间件函数');
    // 把流转关系,转交给下一个中间件或者路由
    next()
}

app.use(mw)
中间件的 作用
多个中间件之间, 共享同一份 req res 。基于这样的特性,我们可以在 上游 的中间件中, 统一 为 req 或 res 对象添
自定义 属性 方法 ,供 下游 的中间件或路由进行使用。
Express 中间件_第3张图片

 定义多个全局中间件

可以使用 app.use() 连续定义多个 全局中间件。客户端请求到达服务器之后,会按照中间件 定义的先后顺序 依次进行 调用
app.use(function (req, res,next){
    console.log('调用第一个全局中间件');
    next()
})

app.use(function (req, res,next){
    console.log('调用第二个全局中间件');
    next()
})

app.get('/user', (req, res) => {
    // 请求这个路由,会依次触发上述两个全局中间件
    res.send('home page')
})
局部生效 的中间件
不使用 app.use() 定义的中间件,叫做 局部生效的中间件
// 定义中间件函数 mv1
const mv1 = (req, res, next) => {
    console.log('这是1中间件函数');
    next()
}
// mv1 这个中间件只在"当前路由中生效",这种用法属于"局部生效的中间件"
app.get('/', mv1,function (req, res) {
    res.send('Home page')
})
//mv1 这个中间件不会影响下面这个路由
app.get('/user', function (req, res) {
    res.send('User page')
})
定义 多个 局部中间件
可以在路由中,通过如下两种 等价 的方式, 使用多个局部中间件
const express = require('express')
const app = express()
// 定义中间件函数 mv1
const mv1 = (req, res, next) => {
    console.log('这是1中间件函数');
    next()
}

const mv2 = (req, res, next) => {
    console.log('这是2中间件函数');
    next()
}
// mv1 这个中间件只在"当前路由中生效",这种用法属于"局部生效的中间件"
// 多个局部中间件,使用数组形式也可以
// app.get('/', [mv1,mv2], function (req, res)
app.get('/', mv1,mv2,function (req, res) {
    console.log('ok');
    res.send('Get user list')
})

app.get('/user', function (req, res) {
    res.send('Get user list')
})

app.listen(3001, () => {
    console.log('http://127.0.0.1:3001');
})
中间件的5个使用注意事项
一定要在 路由之前 注册中间件
客户端发送过来的请求, 可以连续调用多个 中间件进行处理
执行完中间件的业务代码之后, 不要忘记调用 next() 函数
为了 防止代码逻辑混乱 ,调用 next() 函数后不要再写额外的代码
连续调用多个中间件时,多个中间件之间, 共享 req 和 res 对象
中间件的5 大类
应用级别 的中间件
路由级别 的中间件
错误级别 的中间件
Express 内置 的中间件
第三方 的中间件
应用级别 的中间件
通过 app.use() app.get() app.post() 绑定到 app 实例上的中间件 ,叫做应用级别的中间件
路由级别 的中间件
绑定到 express.Router() 实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不
过, 应用级别中间件是绑定到 app 实例上 路由级别中间件绑定到 router 实例上
错误级别 的中间件
错误级别中间件的 作用 :专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。
格式 :错误级别中间件的 function 处理函数中, 必须有 4 个形参 ,形参顺序从前到后,分别是 ( err , req, res, next)。
注意: 错误级别的中间件, 必须注册在所有路由之后
Express内置 的中间件
自 Express 4.16.0 版本开始,Express 内置了 3 个 常用的中间件,极大的提高了 Express 项目的开发效率和体验:
express.static 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)
express.json 解析 JSON 格式的请求体数据( 有兼容性 ,仅在 4.16.0+ 版本中可用)
express.urlencoded 解析 URL-encoded 格式的请求体数据( 有兼容性 ,仅在 4.16.0+ 版本中可用)
第三方 的中间件
非 Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以 按需下载 配置
第三方中间件,从而提高项目的开发效率。
例如:在 [email protected] 之前的版本中,经常使用 body-parser 这个第三方中间件,来解析请求体数据。使用步
骤如下:
运行 npm install body-parser 安装中间件
使用 require 导入中间件
调用 app.use() 注册并使用中间件
注意: Express 内置的 express.urlencoded 中间件,就是基于 body-parser 这个第三方中间件进一步封装出来的。
自定义中间件
实现步骤:
定义中间件
监听 req 的 data 事件
监听 req 的 end 事件
使用 querystring 模块解析请求体数据
将解析出来的数据对象挂载为 req.body
将自定义中间件封装为模块
const express = require('express')

const app = express()

// 定义全局生效的中间件
// 中间件作用:共享同一份 req,res
app.use(require('./13.custom-body-parser'))

app.post('/login', (req, res) => {
    console.log(req.body);
})

app.listen(3001, () => {
    console.log('http://127.0.0.1:3001');
})
自定义中间件 封装 为模块
为了优化代码的结构,我们可以把自定义的中间件函数, 封装为独立的模块
// nodejs 内置模块 querystring --->将查询字符串格式的数据解析为对象格式
const qs = require('querystring')
module.exports = (req, res, next) => {
    // 处理 post 提交过来的数据 处理的数据 挂载到 req.body 身上
    let str = '';
    // data事件分批次接受到客户端提交过来的数据
    req.on('data', (chunk) => {
        str += chunk
    })
    // 当end事件被触发了 就表示数据已经传递完了
    req.on('end', () => {
        // console.log(str);
        req.body = qs.parse(str)
        next()
    })
}

你可能感兴趣的:(node.js,javascript)