
本文详解 fetch() 发送 json post 请求时常见的错误(如请求体未正确序列化、缺少错误捕获机制),并提供可直接运行的修复代码、关键注意事项及与 jquery 的行为对比分析。
在前端开发中,fetch() 是现代浏览器推荐的原生网络请求方案,但其行为与 jQuery 的 $.ajax() 存在关键差异——尤其在请求体序列化、错误处理时机和 Promise 链管理上。你遇到的“仅返回 model 信息、缺失 text 字段”问题,并非后端随机错误,而是典型的客户端请求构造缺陷。
? 根本原因分析
你的原始代码存在两个核心问题:
-
body 未序列化为 JSON 字符串
fetch() 的 body 选项要求是 string、Blob、FormData 等底层类型,不能直接传入 JavaScript 对象数组。而 jQuery 的 $.ajax() 会自动调用 JSON.stringify() 并设置 Content-Type: application/json。你的代码中:body: [ { content: 'who won...', role: 'user' } ] // ❌ 对象数组,未转字符串实际发送的是 [object Object],服务端无法解析,导致字段丢失或降级响应。
try/catch 无法捕获异步 Promise 错误
fetch(url, options) 立即返回 Promise,try/catch 只能捕获同步异常(如语法错误),对网络失败、HTTP 错误码(如 400/500)、JSON 解析失败等异步拒绝(rejected Promise)完全无效。这导致错误被静默吞没,调试困难。
✅ 正确实现:三步修复
以下是修复后的完整、健壮的 fetch() 示例:
Fetch POST Example
⚠️ 关键注意事项
- Content-Type 头必须显式设置:fetch() 不会自动推断,遗漏会导致服务端拒绝解析。
- 始终检查 response.ok:fetch() 在网络失败时才 reject,但 HTTP 4xx/5xx 状态码仍会 resolve,需手动判断。
- 避免混合错误处理模式:不要在 fetch() 外层用 try/catch,所有错误应统一在 .catch() 或 async/await 的 try/catch 中处理。
- 对比 jQuery 的行为:jQuery 默认启用 contentType: 'application/json' 并自动 JSON.stringify(),掩盖了底层细节;fetch() 要求开发者显式控制,更透明但也更易出错。
? 总结
fetch() 的“失效”本质是请求构造不合规与错误处理不完整所致。修复只需两处关键修改:将请求体 JSON.stringify() 后传入 body,并将错误捕获移至 Promise 链末尾的 .catch()。掌握这一模式,不仅能解决当前问题,更能避免绝大多数 fetch() 集成陷阱。









