fetch 收到 404/500,为什么 catch 没有执行
写前端请求时,容易把“进入 catch”理解成“服务器返回了错误”。但 fetch() 不会仅仅因为 HTTP 状态是 404 或 500 就拒绝 Promise。能够取得 Response 时,HTTP 状态是否代表成功,要由代码判断。
最直接的检查是 response.ok,它在状态码为 200–299 时为 true:
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
这里假设成功响应有 JSON 正文。如果接口返回 204,没有正文,就不要直接调用 json()。错误响应也可能是 HTML 或纯文本;需要保留详情时,可以先记下状态码,再读取 text(),有明确格式约定后再解析。否则,JSON 解析失败反而可能遮住原来的 HTTP 错误。
本地临时 HTTP 服务器分别返回了 200 JSON、404 文本和 500 JSON。三个 fetch() 都正常 fulfilled,后两者的 ok 为 false;请求不可用端口则抛出 TypeError,主动取消请求会得到 AbortError。测试环境是 Node.js,浏览器中还可能遇到 CORS 等限制。
还有一个容易误判的情况:POST 进入 catch,并不等于服务端没收到。本地补做的实验中,服务器先接收一次 POST 并增加计数,再主动断开连接;客户端得到 TypeError: fetch failed,但服务端计数已经是 1。这个结果说明“没拿到响应”和“请求未被处理”不是一回事,不代表所有网络错误都已经执行成功。
遇到这种结果不明的写请求,先查业务记录、请求编号或服务端日志,不要仅凭 catch 自动再发一次。若接口支持幂等键,重试同一业务操作时应沿用同一个键,并由服务端正确处理,而不是每次重试都生成新键。
排查时把三个阶段分开会清楚得多:fetch() 是否拿到响应、HTTP 状态是否符合预期、正文是否按约定解析成功。
参考资料:
MDN — Using the Fetch API https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
MDN — Window.fetch() https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch
MDN — Response.ok https://developer.mozilla.org/en-US/docs/Web/API/Response/ok
本文由 AI 辅助整理,示例已在本地运行核对。
- 点赞
- 收藏
- 关注作者
评论(0)