Node.js Express 中如何解决 POST 请求 req.body 为空的问题
问题核心原因
- 配置
mode: "no-cors"触发了浏览器的请求限制:
no-cors是浏览器为跨域场景设计的受限请求模式,该模式下仅允许发送符合“简单请求”规则的报文,自定义设置的application/json格式Content-Type头不在规则允许范围内,会被浏览器强制改写为text/plain,根本不会按照你配置的请求头传递到服务端。
服务端配置的express.json()中间件,只会解析Content-Type为application/json的请求体;拿到被浏览器改写后的请求头后,中间件会直接跳过解析逻辑,给req.body赋值为空对象,整个过程不会抛出任何明显错误。 - body参数未做序列化处理:
fetch API本身不会自动把传入的原生JS对象转成合法的JSON字符串,哪怕跨域限制完全放开,直接将JS对象作为body参数传入,浏览器也会将其转成无意义的字符串[object Object],服务端拿到的内容根本不是可解析的JSON结构。
可直接落地的修复方案
- 移除请求配置里的
mode: "no-cors"参数,走fetch默认的cors模式。不要用no-cors模式发送需要传递结构化JSON的POST请求,该模式下浏览器会完全屏蔽请求对应的响应内容,本身就不适合有正常业务交互的接口场景。 - 用
JSON.stringify()将需要发送的JS对象序列化为合法字符串后,再赋值给请求的body字段。 - 服务端添加cors跨域规则,避免浏览器拦截正常的跨域请求:
- 通过npm安装cors依赖包
- 在路由初始化、
express.json()中间件之前挂载cors中间件
const cors = require('cors'); app.use(cors()); app.use(express.json()); - 调整完成后的前端请求代码示例:
let opts = { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ "test": "test" }) } fetch("http://localhost:3001/data", opts)
补充说明:Express内置的所有请求体解析中间件,都会在请求的Content-Type和自身支持的格式不匹配时,跳过解析逻辑,直接将req.body初始化为空对象,不会触发报错,这也是排查过程中看不到明确错误提示、仅能看到空对象返回的核心原因。
内容的提问来源于stack exchange,提问作者Alon Raz
相关产品推荐
相关产品推荐

