Fetch API 默认不校验HTTP状态码,404/500等仍会resolve,须手动检查response.ok或status;JSON响应需await response.json()并防空体;POST需JSON.stringify+正确headers;无内置超时,需AbortController实现。

Fetch API 是现代 JavaScript 发起网络请求的首选方式,它比 XMLHttpRequest 更简洁、更符合 Promise 语义,且原生支持 async/await。但直接用 fetch() 容易忽略错误处理和状态判断——它只在“网络失败”时 reject,而 HTTP 错误状态(如 404、500)仍会 resolve。
fetch() 默认不校验 HTTP 状态码
调用 fetch(url) 后,即使服务器返回 404 或 500,Promise 依然会进入 then(),而不是 catch()。必须手动检查 response.ok 或 response.status。
-
response.ok是布尔值,等价于response.status >= 200 && response.status - 常见写法是链式调用:
fetch(url).then(r => { if (!r.ok) throw new Error(r.status); return r.json(); }) - 如果不检查,
r.json()在非 2xx 响应下仍会执行,但后续解析可能失败或得到意外数据
如何正确处理 JSON 接口响应
多数 REST API 返回 JSON,但 response.json() 是一个异步方法,必须等待其 Promise 完成。不能假设 response.body 是已解析对象。
- 必须写成
response.json().then(data => {...})或const data = await response.json() - 如果接口返回空响应体(如 204 No Content),调用
.json()会抛出 SyntaxError,需提前用response.headers.get('content-type')?.includes('json')判断 - 不要在
fetch()外层直接return response.json(),否则上层拿到的是 Promise,不是数据
POST 请求要配齐 headers 和 body
发送 JSON 数据时,Content-Type 必须显式设为 application/json,且 body 要是字符串(不是对象)。
立即学习“Java免费学习笔记(深入)”;
- 错误写法:
body: { name: 'a' }→ 会转成[object Object] - 正确写法:
body: JSON.stringify({ name: 'a' }),并配headers: { 'Content-Type': 'application/json' } - 如果后端接收表单数据(
application/x-www-form-urlencoded),要用new URLSearchParams(formData).toString()构造 body - GET 请求无需设置
body,参数应拼在 URL 后(或用URL构造)
fetch 没有超时控制,需要手动实现
fetch() 本身不支持 timeout 选项,网络卡住时会一直 pending。必须用 AbortController 配合 Promise.race() 或封装超时逻辑。
- 创建控制器:
const controller = new AbortController(); - 传入 signal:
fetch(url, { signal: controller.signal }) - 超时触发:
setTimeout(() => controller.abort(), 8000) - 注意:
controller.abort()会让 fetch Promise reject 并抛出AbortError,需单独捕获
最常被跳过的其实是错误分支的完备性——比如没处理 TypeError(网络中断)、没区分 AbortError(超时)和业务错误(401/403)。真实项目里,这些边界情况往往比主体逻辑更影响体验。











