fetch 收到 404/500,为什么 catch 没有执行

举报
yd_275510632 发表于 2026/10/25 03:01:01 2026/10/25
【摘要】 fetch() 返回 Response 不代表 HTTP 状态成功。404、500 本身不会让它自动进入 catch,应主动检查 response.ok。网络中断、取消请求和正文解析错误还要分别处理;尤其不能凭 catch 就认定 POST 没有被服务端接收。

写前端请求时,容易把“进入 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 辅助整理,示例已在本地运行核对。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。