前端fetch发送POST请求后端收到空对象问题排查
问题原因
核心问题出在前端fetch请求配置的mode: 'no-cors'参数,这是导致后端接收空对象、请求报错的直接原因,具体逻辑如下:
- 浏览器对
no-cors模式的请求有严格限制:仅允许发送属于简单请求范畴的请求头,你手动设置的Content-Type: application/json不属于简单请求头范围,会被浏览器直接丢弃,请求实际发送的Content-Type会被强制改为text/plain - 后端的JSON解析中间件(Express框架下为
express.json())默认只会解析Content-Type为application/json的请求体,收到text/plain类型的请求时不会做JSON反序列化处理,最终req.body就会是空对象 no-cors模式下前端只能拿到不透明(opaque)响应,无法读取响应状态、响应体内容,你代码中调用res.ok、res.json()的逻辑本身就会触发异常;同时因为跨域请求不符合CORS校验规则,浏览器会直接拦截请求,抛出你看到的net::ERR_CONNECTION_RESET错误- Postman不受浏览器同源策略限制,不需要遵守CORS规则,所以直接发JSON请求可以正常得到响应,这也是接口本身功能正常但前端调用失败的原因。
解决步骤
- 删除前端fetch配置中的
mode: 'no-cors'字段,不要用该模式发送需要传递JSON参数、需要读取响应内容的业务请求 - 给后端服务配置CORS跨域支持(你的前后端端口不同,属于跨域场景,必须配置否则浏览器会拦截请求):
- 先安装cors依赖:
npm install cors- 在Express服务的入口文件中,在注册路由之前添加以下中间件配置:
const express = require('express'); const cors = require('cors'); const app = express(); // 允许跨域请求 app.use(cors()); // 解析JSON格式请求体,确保这个中间件也在路由之前注册 app.use(express.json()); // 后续再注册你的业务路由 - 重启后端服务后重新发起请求,此时请求会正常携带
Content-Type: application/json头,后端可以正确解析请求体,也不会再出现跨域拦截的报错。
注意事项
no-cors模式仅适用于发送不需要读取响应内容的请求(比如埋点上报、像素追踪类请求),但凡需要前端传递JSON参数、读取后端返回结果的接口,都不能用这个模式,跨域问题必须通过后端配置CORS的正规方式解决。
内容的提问来源于stack exchange,提问作者Moon Krater
相关产品推荐
相关产品推荐

