
本文详解 fetch() 在发送 json post 请求时常见的错误原因及修复方法,重点解决因 promise 链未正确捕获异常、请求体格式错误或缺少 await 导致的响应不完整问题,并提供可直接运行的修正代码示例。
在使用 fetch() 发送 POST 请求时,常见误区会导致请求看似“成功”却返回不完整数据(如仅返回 model 字段而缺失 text),而 jQuery 却能正常工作——这并非后端差异,而是 fetch() 的行为特性与错误处理方式所致。
? 核心问题分析
try/catch 无法捕获异步 Promise 错误
原代码中 try { fetch(...) } catch (error) {...} 是无效的:fetch() 立即返回一个 Promise,try/catch 不会等待其 resolve/reject,因此网络错误、4xx/5xx 响应或 JSON 解析失败均无法被捕获。请求体(body)格式错误
原代码中 body: [{ content: "...", role: "user" }] 是一个数组,但目标 API(chatgpt-api8.p.rapidapi.com)实际期望的是 JSON 字符串化的对象(非数组),且需符合其文档要求的结构(如 {"model": "gpt-3.5-turbo", "messages": [...]})。直接传入 JS 数组会导致后端解析失败或降级处理。缺少对 HTTP 状态码的校验
fetch() 在网络失败时 reject,但对 400、401、500 等 HTTP 错误状态仍会 resolve,必须手动检查 response.ok 或 response.status。
✅ 正确写法(含错误处理与结构修复)
Hello
⚠️ 关键注意事项
- 永远 JSON.stringify() body:fetch() 的 body 选项不接受原始对象或数组,必须是 string、Blob、FormData 等;发送 JSON 时务必 JSON.stringify(...)。
- 区分 content-type 大小写:标准 Header 名为 Content-Type(首字母大写),虽多数服务兼容小写,但建议遵循规范。
- jQuery “能用” 的原因:jQuery 的 $.ajax() 默认自动 JSON.stringify() 并内置更宽松的错误分类(如将 4xx 视为 error),掩盖了底层问题;而 fetch() 更底层、更严格,需开发者显式处理。
- 不要混用 async/await 和 .then():选择一种风格保持代码清晰。上方示例使用 async/await,更易读且 try/catch 真正生效。
✅ 总结
fetch() 不是 jQuery 的替代品,而是更现代、更可控的原生方案——但它要求你理解 Promise 流程、HTTP 语义和序列化规则。只要确保:① body 正确序列化,② 检查 response.ok,③ 使用 async/await 或链式 .catch() 处理错误,就能稳定获取完整响应(包括 model 和 text)。









