前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# 常用中间件 body_parser 实现解析

30 秒速记

  • 请求体在 Node.js 里是一段字节流,req.body 是解析中间件挂上去的,不是天生就有
  • Express 4.16+ 内置 express.json() / express.urlencoded(),底层就是 body-parser
  • 解析链路:收字节 → 按 Content-Encoding 解压 → 按 charset 解码 → 按 Content-Type 解析
  • 默认上限 100kb,超了 413;JSON 写错 400;类型不匹配就跳过,req.body 拿不到值
  • 解析成功 ≠ 字段合法,还要做 schema 校验;webhook 验签要用 verify 留住原始字节

body-parser 干的事就是把请求体这段字节流读完、解压、解码,再按类型解析成对象挂到 req.body 上。 很多人以为 req.body 是 Express 自带的,其实不注册解析中间件它就是空的,Express 4 里是 undefined,用了 body-parser 1.x 但类型不匹配时是 {}。现在 Express 4.16 以后直接用 express.json() 就行,不用单独装包。实际项目里我最在意的是三件事:限制大小、出错要返回明确的 4xx、解析出来的数据还得过一遍校验。

理解「常用中间件 body_parser 实现解析」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 middleware 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

HTTP 请求到了 Node.js 里,req 是一个可读流,请求体要自己监听 data 和 end 事件一段一段收。body-parser 就是把这件事封装成中间件,收完以后解析好挂到 req.body,后面的路由直接用。

在 Express 里一般这样写:

const express = require('express');
const app = express();

app.use(express.json({ limit: '100kb' }));          // application/json
app.use(express.urlencoded({ extended: false }));   // 普通表单

app.post('/users', (req, res) => {
  res.json({ name: req.body.name });
});

// 解析失败统一兜底
app.use((err, req, res, next) => {
  if (err.type === 'entity.parse.failed') return res.status(400).json({ msg: 'JSON 格式错误' });
  if (err.type === 'entity.too.large') return res.status(413).json({ msg: '请求体过大' });
  next(err);
});

app.listen(3000);
@前端进阶之旅: 代码已经复制到剪贴板

几个版本差异要分清:Express 4.16 之前必须单独装 body-parser;4.16 起 express.json() 和 express.urlencoded() 内置,本质是同一套代码。Express 5 配套的是 body-parser 2.x,urlencoded 的 extended 默认改成了 false,而且没有任何解析器匹配时 req.body 是 undefined,不再是 {},老代码里 if (req.body.xxx) 这种写法升级时要留意。

文件上传用的 multipart/form-data 不归 body-parser 管,要用 multer、busboy 这类专门的库。

面试官追问

追问 1路由里 req.body 一直是 undefined,最先查什么?
参考回答

先看有没有注册 express.json(),以及它是不是在路由之前 app.use 的。顺序对了还不行,就看请求头的 Content-Type,前端发的不是 application/json 的话,json() 会直接跳过不解析。

追问 2前端传了一个 200KB 的 JSON,后端直接报 413,为什么?
参考回答

body-parser 默认 limit 是 100kb,超了就返回 413 Payload Too Large。按接口放开就行,比如 express.json({ limit: '1mb' }) 只挂在导入接口上,别全局一刀切调大。

追问 3前端发了个格式错误的 JSON,服务返回了一大段 HTML 报错页,怎么改?
参考回答

body-parser 解析失败会 next(err),带上 err.status = 400 和 err.type = 'entity.parse.failed',没写错误处理中间件就会走 Express 默认的 HTML 错误页。补一个四参数的错误中间件,按 err.type 返回统一的 JSON 错误。

追问 4接 Stripe 这类 webhook 要验签,可是 req.body 已经被解析成对象了怎么办?
参考回答

签名是对原始字节算的,JSON.stringify(req.body) 重新序列化出来的字符串大概率对不上。用 express.json({ verify: (req, res, buf) => { req.rawBody = buf } }) 把原始 Buffer 留下来,或者这个路由单独用 express.raw({ type: 'application/json' })。

追问 5JSON 能解析成功,是不是就可以直接存库了?
参考回答

不行,解析只保证语法对,{"age": "abc"} 一样能解析。字段类型、必填、长度都要用 zod、joi 这类库校验,多余字段也要明确是丢弃还是报错。

# 写在前面

30 秒速记

  • 两行覆盖大部分场景:bodyParser.json() 解 JSON,bodyParser.urlencoded({ extended: false }) 解表单
  • 每个解析器只认自己的 Content-Type,不匹配就放行,不报错也不解析
  • 必须注册在路由之前,中间件按 app.use 的顺序执行
  • extended: false 用 querystring,true 用 qs,能解析 a[b]=1 这种嵌套
  • Express 4.16+ 直接写 express.json(),不用再装包

body-parser 是 Express 里专门解析请求体的中间件,json 和 urlencoded 两行就能覆盖绝大多数接口。 它的工作方式是看请求的 Content-Type,匹配上了才去读流、解析,挂到 req.body,没匹配上就直接 next()。所以前端发 JSON、后端只注册了 urlencoded,req.body 就是空的,这锅不在前端。新项目我一般直接用 Express 内置的 express.json(),效果一样。

body-parser是非常常用的一个express中间件,作用是对http请求体进行解析。使用非常简单,以下两行代码已经覆盖了大部分的使用场景。

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
@前端进阶之旅: 代码已经复制到剪贴板

本文从简单的例子出发,探究body-parser的内部实现。至于body-parser如何使用,感兴趣的同学可以参考 官方文档。

面试官追问

追问 1前端发 JSON 到 /login,后端只注册了 urlencoded,req.body 是空的,是前端没传吗?
参考回答

不是,数据传到了,只是没有解析器认领它。urlencoded() 只处理 application/x-www-form-urlencoded,JSON 请求被跳过了。补上 express.json() 就行。

追问 2把 app.use(bodyParser.json()) 写在路由定义后面,会怎样?
参考回答

请求按注册顺序走中间件,先命中路由处理函数,那时候还没人解析请求体,req.body 自然是空的。解析中间件要放在依赖它的路由之前。

追问 3表单要提交 user[name]=tom&user[age]=18,extended: false 能解析成嵌套对象吗?
参考回答

不能,false 用的是 querystring,会得到 { 'user[name]': 'tom', ... } 这样的平铺键。要嵌套就改成 extended: true 用 qs,但它会带来深度和数组的复杂输入,记得控制 parameterLimit 和深度,结构复杂的数据我更倾向让前端直接发 JSON。

追问 4全局挂解析器和按路由挂,怎么选?
参考回答

大部分接口都收 JSON 就全局挂,省事。只有个别接口要大 limit、或者 webhook 需要原始字节,就单独在那个路由上挂 express.raw() 或者 express.json({ limit: '5mb' }),注意别让全局的解析器先把流读掉了。

基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
      • 写在前面
      • 入门基础
      • body-parser主要做了什么
      • 一、处理不同类型请求体
        • 解析text/plain
        • 解析application/json
        • 解析application/x-www-form-urlencoded
      • 二、处理不同编码
      • 三、处理不同压缩类型
      • 写在后面
      • 相关链接
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

常用中间件 body_parser 实现解析|Nodejs专题系列

# 常用中间件 body_parser 实现解析

30 秒速记

  • 请求体在 Node.js 里是一段字节流,req.body 是解析中间件挂上去的,不是天生就有
  • Express 4.16+ 内置 express.json() / express.urlencoded(),底层就是 body-parser
  • 解析链路:收字节 → 按 Content-Encoding 解压 → 按 charset 解码 → 按 Content-Type 解析
  • 默认上限 100kb,超了 413;JSON 写错 400;类型不匹配就跳过,req.body 拿不到值
  • 解析成功 ≠ 字段合法,还要做 schema 校验;webhook 验签要用 verify 留住原始字节

body-parser 干的事就是把请求体这段字节流读完、解压、解码,再按类型解析成对象挂到 req.body 上。 很多人以为 req.body 是 Express 自带的,其实不注册解析中间件它就是空的,Express 4 里是 undefined,用了 body-parser 1.x 但类型不匹配时是 {}。现在 Express 4.16 以后直接用 express.json() 就行,不用单独装包。实际项目里我最在意的是三件事:限制大小、出错要返回明确的 4xx、解析出来的数据还得过一遍校验。

理解「常用中间件 body_parser 实现解析」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 middleware 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

HTTP 请求到了 Node.js 里,req 是一个可读流,请求体要自己监听 data 和 end 事件一段一段收。body-parser 就是把这件事封装成中间件,收完以后解析好挂到 req.body,后面的路由直接用。

在 Express 里一般这样写:

const express = require('express');
const app = express();

app.use(express.json({ limit: '100kb' }));          // application/json
app.use(express.urlencoded({ extended: false }));   // 普通表单

app.post('/users', (req, res) => {
  res.json({ name: req.body.name });
});

// 解析失败统一兜底
app.use((err, req, res, next) => {
  if (err.type === 'entity.parse.failed') return res.status(400).json({ msg: 'JSON 格式错误' });
  if (err.type === 'entity.too.large') return res.status(413).json({ msg: '请求体过大' });
  next(err);
});

app.listen(3000);
@前端进阶之旅: 代码已经复制到剪贴板

几个版本差异要分清:Express 4.16 之前必须单独装 body-parser;4.16 起 express.json() 和 express.urlencoded() 内置,本质是同一套代码。Express 5 配套的是 body-parser 2.x,urlencoded 的 extended 默认改成了 false,而且没有任何解析器匹配时 req.body 是 undefined,不再是 {},老代码里 if (req.body.xxx) 这种写法升级时要留意。

文件上传用的 multipart/form-data 不归 body-parser 管,要用 multer、busboy 这类专门的库。

面试官追问

追问 1路由里 req.body 一直是 undefined,最先查什么?
参考回答

先看有没有注册 express.json(),以及它是不是在路由之前 app.use 的。顺序对了还不行,就看请求头的 Content-Type,前端发的不是 application/json 的话,json() 会直接跳过不解析。

追问 2前端传了一个 200KB 的 JSON,后端直接报 413,为什么?
参考回答

body-parser 默认 limit 是 100kb,超了就返回 413 Payload Too Large。按接口放开就行,比如 express.json({ limit: '1mb' }) 只挂在导入接口上,别全局一刀切调大。

追问 3前端发了个格式错误的 JSON,服务返回了一大段 HTML 报错页,怎么改?
参考回答

body-parser 解析失败会 next(err),带上 err.status = 400 和 err.type = 'entity.parse.failed',没写错误处理中间件就会走 Express 默认的 HTML 错误页。补一个四参数的错误中间件,按 err.type 返回统一的 JSON 错误。

追问 4接 Stripe 这类 webhook 要验签,可是 req.body 已经被解析成对象了怎么办?
参考回答

签名是对原始字节算的,JSON.stringify(req.body) 重新序列化出来的字符串大概率对不上。用 express.json({ verify: (req, res, buf) => { req.rawBody = buf } }) 把原始 Buffer 留下来,或者这个路由单独用 express.raw({ type: 'application/json' })。

追问 5JSON 能解析成功,是不是就可以直接存库了?
参考回答

不行,解析只保证语法对,{"age": "abc"} 一样能解析。字段类型、必填、长度都要用 zod、joi 这类库校验,多余字段也要明确是丢弃还是报错。

# 写在前面

30 秒速记

  • 两行覆盖大部分场景:bodyParser.json() 解 JSON,bodyParser.urlencoded({ extended: false }) 解表单
  • 每个解析器只认自己的 Content-Type,不匹配就放行,不报错也不解析
  • 必须注册在路由之前,中间件按 app.use 的顺序执行
  • extended: false 用 querystring,true 用 qs,能解析 a[b]=1 这种嵌套
  • Express 4.16+ 直接写 express.json(),不用再装包

body-parser 是 Express 里专门解析请求体的中间件,json 和 urlencoded 两行就能覆盖绝大多数接口。 它的工作方式是看请求的 Content-Type,匹配上了才去读流、解析,挂到 req.body,没匹配上就直接 next()。所以前端发 JSON、后端只注册了 urlencoded,req.body 就是空的,这锅不在前端。新项目我一般直接用 Express 内置的 express.json(),效果一样。

body-parser是非常常用的一个express中间件,作用是对http请求体进行解析。使用非常简单,以下两行代码已经覆盖了大部分的使用场景。

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
@前端进阶之旅: 代码已经复制到剪贴板

本文从简单的例子出发,探究body-parser的内部实现。至于body-parser如何使用,感兴趣的同学可以参考 官方文档。

面试官追问

追问 1前端发 JSON 到 /login,后端只注册了 urlencoded,req.body 是空的,是前端没传吗?
参考回答

不是,数据传到了,只是没有解析器认领它。urlencoded() 只处理 application/x-www-form-urlencoded,JSON 请求被跳过了。补上 express.json() 就行。

追问 2把 app.use(bodyParser.json()) 写在路由定义后面,会怎样?
参考回答

请求按注册顺序走中间件,先命中路由处理函数,那时候还没人解析请求体,req.body 自然是空的。解析中间件要放在依赖它的路由之前。

追问 3表单要提交 user[name]=tom&user[age]=18,extended: false 能解析成嵌套对象吗?
参考回答

不能,false 用的是 querystring,会得到 { 'user[name]': 'tom', ... } 这样的平铺键。要嵌套就改成 extended: true 用 qs,但它会带来深度和数组的复杂输入,记得控制 parameterLimit 和深度,结构复杂的数据我更倾向让前端直接发 JSON。

追问 4全局挂解析器和按路由挂,怎么选?
参考回答

大部分接口都收 JSON 就全局挂,省事。只有个别接口要大 limit、或者 webhook 需要原始字节,就单独在那个路由上挂 express.raw() 或者 express.json({ limit: '5mb' }),注意别让全局的解析器先把流读掉了。

追问 5为什么 body-parser 的注册顺序这么敏感,普通工具函数就没这个问题?
参考回答

因为请求体是个流,只能读一次,而且是中间件链式执行,谁先执行谁先读。工具函数是业务代码主动调用的,什么时候调都行;中间件是被动地按顺序跑,排错了位置后面就拿不到结果。

# 入门基础

30 秒速记

  • 请求体解析要看三样:Content-Type、Content-Encoding、报文主体
  • Content-Type = 主体格式 + 字符集,如 application/json; charset=utf-8
  • Content-Encoding = 压缩方式:gzip / deflate / identity(不压缩)
  • 处理顺序:先解压,再按 charset 解码成字符串,最后按类型解析
  • 压缩和字符集是两层,别搞混:gzip 后的字节不是文本,不能直接 toString()

解析请求体之前,要先看懂两个请求头:Content-Type 告诉你内容是什么格式、什么字符集,Content-Encoding 告诉你有没有压缩。 可以想象成收快递:Content-Encoding 是包装方式,先拆箱;charset 是说明书用的什么语言,拆完按这个语言读;Content-Type 是里面装的东西是什么,最后按类型处理。顺序反了就会出乱码,比如 gzip 过的数据还没解压就 toString(),看到的全是乱码。

← 将图片转成datauri嵌入到html日志模块morgan →

fe