Express 中间件 body-parser 原理分析

Express中间件机制解析与最佳实践 中间件是现代Web开发中的核心概念,本质是位于请求和响应之间的处理层。其工作原理遵循洋葱模型,通过预处理和后处理两个阶段实现功能解耦。在Node.js生态中,Express框架的中间件系统尤为典型,支持路由级拦截、异步流程控制等关键技术特性。合理使用中间件可以显著提升代码复用率,在权限校验、日志记录、性能监控等通用场景下效果显著。本文以电商平台API开发为例,详解如何通过200行代码实现统一处理逻辑,并分享中间件类型划分、加载顺序控制等实战经验,特别针对错误处理、内存泄漏等高频问题提供解决方案。 阅读详情

在这里插入图片描述


阅读原文


前言

Express 是基于 NodeJS 平台的 Web 框架,应用广泛,在 Express 社区中有着大量的开发者通过 Express 中间件的特性,开发了各种功能的中间件,用来处理某些响应以及给请求对象 req、响应对象 res 添加属性或方法,我们接下来就通过分析常用的 body-parser 中间件的原理来了解如何开发 Express 中间件,如果想了解更多 Express 内部封装原理可以看 《Express 源码分析及简易封装》。


body-parser 的基本使用

想刨析一个中间件的原理,首先应该从使用入手,在足够了解用法的基础上去分析,现在搭建一个简易的 Express 服务,并使用 body-parser 中间件,使用前需安装。

npm install express body-parser

使用 body-parser 代码如下:

const express = require("express");
const bodyParser = require("body-parser");

// 创建服务
const app = express();

// 使用 body-parser 中间
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// 创建路由
app.post("/login", function (req, res) {
    console.log(req.body);
    res.send(req.body);
});

// 监听服务
app.listen(3000, function () {
    console.log("server start 3000");
});

启动上面的服务器,通过 postman 工具分别通过表单提交和 json 的格式访问 http://localhost:3000/login,查看服务器控制后台的打印结果和 postman 的返回结果。


body-parser 的实现

1、原理分析

从上面的使用案例我们可以分析出一下几点:

  • 首先,body-parser 中间件的作用是给 req 添加属性 body,值为对象,以键值对的形式存储请求体中的参数;
  • 其次,body-parser 只处理 POST 请求;
  • 最后,body-parser 模块导出一个对象,上面有两个方法 urlencoded 和 json,分别处理表单提交和 json 格式的请求体参数。

2、分析 urlencoded、json 公共逻辑

在实现之前我们先分析一下两个方法,首先都需要先读取请求体中的内容,数据传输的类型为 Buffer,转换成字符串后会根据提交方式不同而导致请求体中的内容是查询字符串或者是 json 字符串的区别。

当解析失败时都需要做错误处理,当不是 POST 请求时都需要向下执行其他中间件,而最核心的事就是把请求体中的数据转换成对象挂在 req.body 上。

使用的转换数据的方法不同是唯一的区别,能区分两者的就是请求头 Content-Type 的值,因此我们可以把所有的公共逻辑抽取出来用一个 acceptPost 函数来执行。

3、模块的创建

我们下面创建自己的 body-parser 模块,防止命名冲突,我们的模块命名为 my-body-parser,处理参数需要使用 querystring 和 qs 两个模块,其中 qs 是第三方模块,使用前需安装。

npm install qs

qs 和 querystring 作用基本相同,就是处理查询字符串格式的参数,但是也有一点小小的区别,querystring 只能处理一级,而 qs 可以处理多级。

const querystring = require("querystring");
const qs = require("qs");

// urlencoded 和 json 公共逻辑
function acceptPost() {
    // ...
}

// 处理表单提交的方法
function urlencoded() {
    // ...
}

// 处理请求体 json 的方法
function json() {
    // ...
}

// 导出对象
module.exports = { urlencoded, json };

在把基本模块搭建好后,我们下面就实现 body-parser 模块内的公共逻辑函数 acceptPost。

4、acceptPost 的实现

为了兼容 urlencoded 方法和 json 方法设计了两个参数,一个是区分当前调用方法的 type,一个是针对 urlencoded 方法的 options。

// acceptPost 的实现
// urlencoded 方法和 json 方法的公共逻辑函数
function acceptPost(type, options) {
    // 返回一个中间件函数
    return function (req, res, next) {
        // 获取请求头
        let contentType = req.headers["content-type"];

        // 判断如果不符合两种提交的请求头直接交给其他中间件处理
        if (
            contentType === "application/x-www-form-urlencoded" ||
            contentType === "application/json"
        ) {
            // 存储数据的数组
            let buffers = [];

            req.on("data", function (data) {
                // 接收数据并存入数组中
                buffers.push(data);
            });

            req.on("end", function () {
                // 组合数据并转换成字符串
                let result = Buffer.concat(buffers).toString();

                // 处理数据并挂载 req.body 属性上
                // 如果是表单提交则使用 querystring 或 qs,否则使用 JSON.parse
                if (type === "form") {
                    // 如果配置 extended 值为 true 使用 qs,否则使用 querystring
                    req.body = options.extended ? qs.parse(result) : querystring.parse(result);
                } else if(type === "json") {
                    req.body = JSON.parse(result);
                }

                next(); // 向下执行
            });

            // 错误处理
            req.on("err", function (err) {
                next(err);
            });
        } else {
            next();
        }
    }
}

5、urlencoded 和 json 方法的实现

// 处理表单提交的方法
function urlencoded(options) {
    // 定义 type 值
    let type = "form";
    return acceptPost(type, options)
}

// 处理请求体 json 的方法
function json() {
    // 定义 type 值
    let type = "json";
    return acceptPost(type);
}

当我们把所有的公共逻辑都抽取出去后发现,urlencoded 和 json 方法内部只需要定义不同的类型就可以执行自己的中间件逻辑。


总结

上面分析 body-parse 中间件的原理的目的在于理解 Express 中间件开发的模式,在此总结一下,Express 中间件返回的是一个函数,形参为 req、res 和 next,当功能无法处理某些情况时需要调用 next,当出现错误时调用 next 并传递错误,则交给 Express 内置的错误处理中间件,在中间件内部代码涉及异步操作时,须在异步完成的回调当中调用 next,这是不如 Koa 方便的一点,同时也是两者的区别,因为 Koa 中已经大量使用 async/await,在执行异步代码时可以等待。


核回归(Kernel Regression) 本文讲解了核函数,并且实战通过核函数进行了预测,并附python代码 阅读详情

相关推荐

WSL2+Docker+Ollama:解锁Windows本地GPU加速运行DeepSeek-R1模型

本文详细介绍了在Windows系统上,通过WSL2、Docker和Ollama的组合方案,实现本地GPU加速运行DeepSeek-R1模型的全过程。该方案解决了Windows环境下Ollama默认无法调用NVIDIA显卡的痛点,通过配置Docker的GPU支持,强制将计算任务分配给GPU,从而显著提升文本生成速度与效率,为开发者提供了一个便捷的本地AI测试环境。

weixin_28452161的博客 357

express 框架body-parser中间件原理解析

nodejs 中 express 框架body-parser中间件原理解析1. express 中的 body-parser 中间件2. 自己封装 bodyParser中间件3. bodyParser.js 原理解析 1. express 中的 body-parser 中间件 在Express 中没有内置获取表单 post 请求体的API,需要借助中间件的第三方包:body-parser 来获取...

@必意玲 4197

基于光电传感的非接触式酒精浓度检测系统设计与实现

本文详细介绍了基于光电传感技术的非接触式酒精浓度检测系统设计与实现。系统利用940nm红外LED和OPT101光电传感器,结合朗伯-比尔定律,通过STM32微控制器进行信号采集与处理,实现了快速、准确的酒精浓度测量,测量精度达±1%,适用于工业检测和便携式应用场景。

y7z8a的博客 364

Express配置post请求的body解析

const app = express();app.post('/api/login', (req, res) => { console.log(req.body); // undefined console.log(req.body['username]); // 报错 console.log(req.body['password']); // 报错 });默认配置的exp

Coder Ben's Writing 6024

Diffusion Model原理详解

Diffusion Model(扩散模型 )对标的是生成对抗网络(GAN),本文将用通俗的语言和公式为大家介绍Diffusion Model,并且结合公式为大家梳理Diffusion Model的代码。

weixin_42620109的博客 6099

如何用SoulChat2.0快速克隆你的心理咨询师?手把手教你搭建AI数字孪生体

本文详细介绍了如何利用SoulChat2.0框架快速构建心理咨询师的AI数字孪生体。通过其核心PsyDT技术,仅需少量真实案例即可合成风格数据并微调大模型,从而低成本地创建能高度模仿特定咨询师语言风格和专业技术的AI分身,适用于预约访谈、心理教育等辅助场景,实现高效的人机协作。

julia4scientist的博客 978

express解析body_如何在Express中同时获取已解析的正文和原始正文

express解析bodyIn one application I’m building, I had this problem. 在我正在构建的一个应用程序中,我遇到了这个问题。 Using Express, I can import body-parser to parse the body as JSON: 使用Express,我可以导入body-parser将body-parser...

cuk0051的博客 1099

基于CNN的表情识别(FER)pytorch实现

Report for FER Jian Tang Abstract 我们使用卷积神经网络(CNN)实现了baby的面部表情识别(FER)。 数据上,我们获取了开源FER数据集FER2013[1],besides我们使用爬虫获取了baby相关的人脸图片,进行了手工分类标注以形成一个全新的baby FER数据集。 模型上,我们首先复现了Luan[2]的工作,即参考Kuo[3]在CVPR 2018上的工作并实现一个轻量的CNN网络,在FER2013上进行训练并得到了XXXX%的平均分类准确率(avg a

qq_20241587的博客 3683

express中间件—body-parser获取post、get数据

1.post请求——req.query //form.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <...

wilL-my的博客 2068

人工智能算法面试大总结-总目录

涉及秋招、春招、社招

啥都生的博客 2万+

【ROS】ROS2导航Nav2:简介、安装、测试效果、错误处理

在ROS2中自动导航使用Nav2来实现。Nav2 使用几个独立的模块化服务,通过 ROS 2接口(例如动作服务器或服务)与行为树 (BT) 通信。Nav2 输入包括:TF转换、一个地图源、一个行为树 (BT) XML 文件和相关的传感器数据源;Nav2 输出速度命令;Nav2 支持多种机器人,比如:四足机器人、履带机器人、轮式机器人等。

郭老二 5083

Express中间件——body-parser

在http请求中,POST、PUT、PATCH三种请求方法中包含着请求体,也就是所谓的request,在Nodejs原生的http模块中,请求体是要基于流的方式来接受和解析。 body-parser是一个HTTP请求体解析的中间件,使用这个模块可以解析JSON、Raw、文本、URL-encoded格式的请求体, Node原生的http模块中,是将用户请求数据封装到了用于请求的对象req中,这个对...

CaseyWei 785

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

中间件 body-parser 原理分析(手写bodyParse))

前言Express是基于 NodeJS 平台的 Web 框架,应用广泛,在Express社区中有着大量的开发者通过Express中间件的特性,开发了各种功能的中间件,用来处理某些...

weixin_43964148的博客 1473

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

express做登录验证获取req.body为空对象问题

用express作登录验证,在代码里打印req.body为空对象,通过解决这个问题对http服务,数据提交到服务器,以及工具的使用有了更加深刻的认识。 出现阻塞的原因 对客户端和服务端通信没有深层次的理解 初次工具使用不熟练 注册登录思路分析 使用express框架搭建web服务器 使用const {Router} = require('express'); const rout...

TyrionJ的博客 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

终极指南:body-parser字符集配置 - 支持UTF-8与ISO-8859-1的完整教程

在Node.js Web开发中,正确处理HTTP请求体是构建健壮应用的基础。body-parser作为Express.js生态中最流行的请求体解析中间件,提供了强大的字符集配置功能,确保你的应用能够正确处理不同编码的请求数据。本文将深入探讨body-parser的字符集配置,特别是UTF-8与ISO-8859-1编码的支持,帮助你构建国际化友好的Web应用。😊 ## 为什么字符集配置如此重要?

gitblog_00312的博客 336

Express中间件(body-parser、cookie-parser、morgan)用法与原理

body-parser 它的作用是对post请求的请求体进行解析,body-parser其实就是当请求发送到服务器时,我们要解析请求,因为请求可以是采用不同请求类型、不同编码、不同压缩类型,所以解析时就要根据不同情况来做不同的解析操作,最终获得客户端发送过来的数据,它的源代码主要做了: 处理不同类型的请求体(Content-Type),比如text,json,urlencoded等,对应的报文...

weixin_34396103的博客 1232

nodejs之express中间件

前言 目前最主流的nodejs框架应该就是express和koa了,二者都是同一个团队开发的。koa更新一点,并且一些设计思想要比express更成熟,不过仍有大量的项目在使用express。 作者对于express框架的定义为“基于 Node.js 平台,快速、开放、极简的 Web 开发框架”。说明express框架本身并没有太多功能,而其大多功能都是通过中间件实现的。由此可见中间件在expre...

铁臂阿凡达的博客 825

关于Express的req.body返回为空的问题

最近打算开发一个前端团队内部使用的api管理系统,也算是正式接触到了nodejs,项目后端使用的是express框架+mongodb数据库。在做登录验证的时候遇到了req.body为空的问题,虽然搞懂后发现确实有些小白了,但还是在此按照当初遇到问题的顺序来记录下,希望能给需要的同学提供一些思路。 问题1:未发现body-parser 后台node服务跑不起来,一直报错没有发现body-parser...

weixin_43460960的博客 6266

终极指南:body-parser与Express 5新特性全解析

body-parser是Node.js中最受欢迎和广泛使用的请求体解析中间件,它为Express框架提供了强大的数据解析能力。在即将到来的Express 5版本中,body-parser将继续发挥重要作用,为开发者提供更高效、更安全的开发体验。🚀 ## body-parser核心功能深度解析 body-parser作为Express生态系统的关键组件,提供了四种主要的解析器类型: - **

gitblog_01048的博客 473

2.实现Express中间件

Express提供的大部分功能都是通过中间件函数完成,这些中间件函数在Node.js收到 请求的时点 和 发送响应的时点 执行 connect模块提供了中间件框剪 方便在全局或路径级别或为单个路由插入中间件功能 (处理POST请求,提供静态文件服务,实现会话,cookie和身份验证) 1.了解中间件 允许在 接收到请求的时点 及 真正处理请求和发送响应的时点 之间附加功...

daxiangya6845的博客 189

body-parser文件上传终极指南:从原理到实战的完整解决方案

在Node.js Web开发中,文件上传是每个开发者都会遇到的常见需求。虽然body-parser本身不直接处理multipart文件上传,但它与其他专业模块的配合使用却能构建出强大而灵活的数据处理系统。本文将深入探讨如何利用body-parser实现高效的文件上传处理。 ## 为什么选择body-parser作为数据处理核心 body-parser作为Express生态中最受欢迎的中间件,专

gitblog_00679的博客 800

深入解析Express中间件机制与实现原理

中间件是Web开发中的核心概念,它作为请求处理管道中的独立单元,实现了业务逻辑的解耦与复用。Express框架通过洋葱模型执行中间件,采用函数式编程思想,将req、res对象和next控制函数作为参数传递。这种设计模式在Node.js生态中被广泛应用,支持从日志记录到身份验证等各种场景。理解中间件的匹配算法和next机制,对于构建高性能Web服务至关重要。本文以Express为例,深入剖析中间件的注册流程、路由匹配原理和异步处理方案,并对比Koa的洋葱圈模型,帮助开发者掌握Web框架的核心设计思想。

areen7003的博客 361

NodeJs扩展模块Express的使用(中间件和第三方中间件)

中间件结构 app.use([path],function) path:是路由的url,默认参数‘/’,意义是路由到这个路径时使用这个中间件 function:中间件函数 这个中间件函数可以理解为就是function(request,response,next) 这里安装是指涉及到第三方中间件的使用时,需要先安装好,然后在使用。 在上面中间件结构中,我们知道了,中间件使用时的第二个参数是一个Fu...

qq_44361433的博客 854

express-session 完全指南:Express 会话中间件的配置、原理与存储实现

`express-session` 是 Express 生态中最常用的会话(session)中间件:它在服务器端保存会话数据,只在浏览器端留下一个**仅含会话 ID 的签名 Cookie**,从而让无状态的 HTTP 请求能够"记住"用户状态。本文以官方 [README.md](https://link.gitcode.com/i/caac9e41f7bc29bc66d9434ccc5d78f9)

gitblog_01411的博客 304

express.urlencoded深入全面讲解教程

专门解析格式请求体,解析后数据挂载在req.body上。核心配置(支持嵌套数据)是绝大多数场景的首选,limit用于限制请求体大小。需与(解析 JSON)、multer(解析文件上传)区分使用,中间件需注册在路由之前。req.body为undefined多是中间件未注册或注册顺序错误,嵌套解析失败需开启。

942
上一篇: Express 源码分析及简易封装
下一篇: NodeJS 进阶 —— Koa 源码分析
Panda Shen
博客等级 码龄10年 18粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值