发送JSON必须显式设置Content-Type: application/json,body需JSON.stringify()转字符串,GET禁用body,应改用POST或URL参数;服务端需匹配中间件(如Express的express.json)。

Fetch发送JSON时必须设置Content-Type请求头
不手动指定Content-Type: application/json,后端大概率收不到数据或解析失败。浏览器不会自动补这个头,即使你传的是JSON.stringify()后的字符串。
常见错误现象:req.body为空(Express)、request.get_json()报错(Flask)、Nginx返回400或415。
- 必须显式在
headers中加入'Content-Type': 'application/json' - 不要依赖
fetch自动推断——它不会推断body内容类型 - 如果后端用
form-data或x-www-form-urlencoded解析器,也会静默丢弃JSON体
body字段只能传字符串,不能直接传对象
fetch的body选项不接受原始JavaScript对象,必须是string、FormData、Blob等可流式读取的类型。直接传{ user: 'a' }会抛出TypeError: Failed to execute 'fetch': Request with GET/HEAD method cannot have body(实际错误更可能是TypeError: Request body is not a valid type)。
- 用
JSON.stringify({ user: 'a', id: 123 })转成字符串再赋给body - 别漏掉
try...catch包裹JSON.stringify()——循环引用对象会直接崩 - 如果对象里有
undefined、function或Symbol,JSON.stringify()会静默忽略它们,可能造成数据丢失
GET请求不能带body,JSON数据得改用URL参数或POST
HTTP规范禁止GET请求携带请求体,尽管部分浏览器(如Chrome)允许发出去,但Node.js原生http模块、Nginx、CDN、某些代理会直接拒绝或丢弃body。想传结构化JSON,只有两个可靠选择:
立即学习“前端免费学习笔记(深入)”;
- 改用
POST(最常用),配合Content-Type: application/json - 把JSON序列化后作为URL查询参数(如
?data=%7B%22user%22%3A%22a%22%7D),但受URL长度限制(通常≤2KB),且需encodeURIComponent(JSON.stringify(...))
别试图用GET + body“试试看”——它在开发环境可能偶然成功,上线后必出问题。
完整可运行示例(含错误处理)
下面这段代码覆盖了95%的JSON POST场景,包含必要头、字符串化、错误分支:
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'user@example.com',
password: 's3cr3t'
})
})
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
console.error('请求失败:', err.message);
});
注意:后端收到的是原始JSON字符串,不是自动解析的对象;是否需要二次JSON.parse(req.body)取决于框架(Express默认需express.json()中间件,Fastify默认自动解析)。
最容易被忽略的一点:服务端中间件顺序。比如Express里express.json()必须在fetch发起请求之前注册,否则req.body永远是undefined。



















