Nodejs -- Express 自定义中间件并进行封装

自定义中间件

1 需求描述与实现步骤

自己手动模拟一个类似于express.urlencoded这样的中间件,来解析POST提交到服务器的表单数据。

  1. 定义中间件
  2. 监听req的data事件
  3. 监听req的end事件
  4. 使用querystring模块解析请求体数据
  5. 将解析出来的数据对象挂载为req.body
  6. 将自定义中间件封装为模块

2 定义中间件

使用app.use()来定义全局生效的中间件,代码如下:

app.use((req, res, next) => {
    // 中间件的业务逻辑
	next()
})

3 监听req的data事件

在中间件中,需要监听req对象的data事件,来获取客户端发送到服务器的数据。

如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后,分批发送到服务器。所以dta事件可能会触发多次,每一次触发dta事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接

// 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
let str = ''

// 2. 监听 req 的data事件
req.on('data', (chunk) => {
    str += chunk
})

4 监听req的end事件

当请求体数据接收完毕之后,会自动触发req的end事件。

因此,我们可以在req的end事件中,拿到并处理完整的请求体数据。示例代码如下:

// 3. 监听 req 对象的 end 事件
req.on('end', () => {
    // 在str中存放的就是完整的请求体数据
    console.log(str)
})

5 使用querystring模块解析请求体数据

Node.js内置了一个querystring模块,专门用来处理查询字符串。通过这个模块提供的parse()函数,可以轻松把查询字符串,解析成对象的格式。示例代码如下:

const qs = require('querystring')

const body = qs.parse(str)

6 将解析出来的数据对象挂载为req.body

上游的中间件和下游的中间件及路由之间,共享同一份req和res。因此,我们可以将解析出来的数据,挂载为req的自定义属性,命茗为req.body, 供下游使用。示例代码如下:

// 3. 监听 req 对象的 end 事件
req.on('end', () => {
    // 在str中存放的就是完整的请求体数据
    const body = qs.parse(str)
    req.body = body
    console.log("中间件", req.body)
    next()
})

7 自定义中间件

为了优化代码的结构,我们可以把自定义的中间件函数,封装为独立的模块,示例代码如下:

//custom-body-parser.js 模块中的代码
const qs = require('querystring')
function bodyParser(req,res,next){/*省略其它代码*/}
module.exports = bodyParser//向外导出解析请求体数据的中间件函数

// ------------------分隔线----------------------
//1,导入自定义的中间件模块
const myBodyParser = require('custom-body-parser')
//2,注册自定义的中间件模块
app.use(myBodyParser)

8 最终代码

index.js

// 导入express
const express = require('express')
const bodyParser = require('./custom-body-parser')

// 创建web服务器
const app = express()

// 解析表单数据的中间件
app.use(bodyParser)

app.post('/user', (req, res) => {
    console.log("路由接口:", req.body)
    res.send(req.body)
})

// 启动服务器
app.listen(80, () => {
    console.log('express server running at http://127.0.0.1')
})

custom-body-parser.js

const qs = require('querystring')

const bodyParser = (req, res, next) => {
    // 定义具体的业务逻辑
    // 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
    let str = ''

    // 2. 监听 req 的data事件
    req.on('data', (chunk) => {
        str += chunk
    })

    // 3. 监听 req 对象的 end 事件
    req.on('end', () => {
        // 在str中存放的就是完整的请求体数据
        req.body = qs.parse(str)
        console.log("中间件", req.body)
        next()
    })
}

module.exports = bodyParser

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hydrion-Qlz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值