Fetch API 不会因 404、500 等 HTTP 错误自动 reject,仅网络失败时 reject;需用 response.ok(等价于 status ≥ 200)手动判断并统一抛错处理。

Fetch API 不会因为 404、500 等 HTTP 错误状态码自动抛错,它只在真正网络失败(如断网、跨域被拒、URL 无效)时 reject。所以处理非 200 状态码必须手动检查响应对象,不能依赖 .catch() 自动捕获。
用 response.ok 判断是否成功
response.ok 是最推荐的方式,它是布尔值,等价于 response.status >= 200 && response.status 。语义清晰、写法简洁,且能覆盖所有常规成功范围(包括 201、204 等)。
- ✅ 正确:拿到 response 后立即判断
if (!response.ok),再决定是否继续解析 JSON - ❌ 错误:跳过检查直接调用
response.json(),此时即使返回 404,代码仍会执行并尝试解析空或错误格式的响应体
按 status 做差异化处理
当需要对不同状态码执行不同逻辑时(比如 401 跳登录、404 提示用户、500 触发重试),应读取 response.status 并配合 switch 或 if/else if 分支处理:
- 优先使用
response.status,它始终可用;response.statusText在某些 CORS 场景下可能为空或受限 - 注意:401 和 403 通常表示认证/权限问题,建议统一导向登录页或弹出授权提示
- 500 类错误可考虑加简单重试机制(如最多 2 次),但需避免无限循环
结合 try/catch 统一收口错误
用 async/await 写法更利于集中管理错误流。网络异常(TypeError)和手动抛出的 HTTP 异常都能被同一 catch 捕获,只需区分错误类型:
立即学习“Java免费学习笔记(深入)”;
- 若
err.name === 'TypeError',基本是网络层问题:离线、DNS 失败、请求被 CORS 阻止、URL 拼错等 - 若
err.message包含 “HTTP error” 或自定义消息,则是服务端返回的业务级错误 - 建议在抛错时带上
status和原始 URL,便于排查
并发请求中的状态码处理
用 Promise.all 发起多个 fetch 时,只要其中任一请求因网络失败而 reject,整个 Promise 就会中断。但 HTTP 错误(如某个接口返回 404)不会导致中断——它仍会进入 .then(),需逐个检查每个 response.ok:
- 推荐先
await Promise.all(promises)获取全部 response 数组 - 再用
Promise.all(responses.map(r => r.ok ? r.json() : Promise.reject(new Error(`${r.status} ${r.statusText}`))))统一处理解析与报错 - 这样既能并发请求,又能把 HTTP 错误也纳入统一错误流


















