Fetch API 是基于 Promise 的原生网络请求接口,其 Promise 不因 HTTP 错误状态码 reject,需手动检查 response.ok;response.body 方法(如 json/text/blob)只能调用一次;POST 需显式设置 Content-Type 和 body 格式;跨域需合理配置 credentials 和 mode。

Fetch API 不是封装好的“请求工具”,它是一套基于 Promise 的原生网络请求接口,用法直接但细节多,稍不注意就会卡在 response.body 读取、错误处理或跨域上。
fetch() 返回的 Promise 永远不会因 HTTP 状态码 reject
这是最常踩的坑:即使服务器返回 404 或 500,fetch() 依然 resolve。必须手动检查 response.ok 或 response.status。
-
response.ok是布尔值,等价于response.status >= 200 && response.status - 如果只依赖
catch,404 错误根本进不去,后续response.json()可能因空响应体抛出 SyntaxError - 建议结构:
fetch('/api/data') .then(response => { if (!response.ok) { throw new Error(`HTTP error: ${response.status}`); } return response.json(); }) .then(data => console.log(data)) .catch(err => console.error('Request failed:', err));
如何正确读取 response body(json/text/blob)
response.json()、response.text()、response.blob() 都是返回 Promise 的方法,且每个只能调用一次 —— body 流一旦被读取就消耗完毕。
- 不能同时写
response.json()和response.text(),后者会 pending 或报错TypeError: Failed to execute 'text' on 'Response': body stream is locked - 上传文件后想读取服务端返回的 JSON?确保后端确实返回了可解析的 JSON,且 Content-Type 正确,否则
response.json()仍会 reject - 需要原始字节或二进制?用
response.arrayBuffer()或response.blob(),别硬转 json
POST 请求必须显式设置 Content-Type 和 body 格式
fetch 默认不带 Content-Type 请求头,且 body 必须是字符串、FormData、Blob 或 URLSearchParams,不能直接传对象。
立即学习“Java免费学习笔记(深入)”;
- 发 JSON:要手动加
headers: { 'Content-Type': 'application/json' },且body: JSON.stringify({ a: 1 }) - 发表单数据:用
new URLSearchParams({ a: '1', b: '2' })(自动设Content-Type: application/x-www-form-urlencoded) - 传文件:必须用
FormData,它会自动生成正确的Content-Type: multipart/form-data; boundary=...,别试图手动拼
credentials 和 mode 对跨域和 Cookie 的影响
默认情况下 fetch 不发送 Cookie,也不接受跨域响应中的 Cookie,除非显式配置。
-
credentials: 'include':带上 Cookie,且要求服务端响应头含Access-Control-Allow-Origin(不能是*)和Access-Control-Allow-Credentials: true -
mode: 'cors'(默认):走 CORS 协商;mode: 'no-cors'会限制响应可读字段(只能读status、ok、type),基本无法用 - 同源请求无需配
credentials,但若后端用了SameSite=Lax/Strict,仍可能因上下文丢失 Cookie
真正麻烦的是组合场景:比如登录后带 token 的请求要 credentials: 'include',而上传图片到第三方 CDN 又得 mode: 'cors' 且不带认证头 —— 这些细节不提前对齐后端策略,前端很容易反复调试 401 或 CORS 报错。











