You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fetch的no-cors模式时,如何区分网络错误与opaque响应?

核心问题

使用fetch的mode: 'no-cors'发起请求时,如何区分opaque响应与网络错误?
我认为:

  • opaque响应会静默失败,fetch的Promise会resolve
  • 网络错误会导致fetch的Promise reject
    能否确认此结论?
背景

我想通过UI检测多个URL是否可达(例如未被防火墙拦截)。有资料提到:

no-cors模式意味着若浏览器需执行任何需要CORS权限的操作,会静默失败而非抛出错误。

具体问题

当使用带no-cors的fetch请求:

  • 遇到网络错误时,是否会导致fetch的Promise reject?
  • 遇到CORS问题时,是否会静默失败,即fetch的Promise resolve?
参考资料
  • 支持:在Chrome开发者工具中模拟域名拦截的网络错误,结果符合上述结论,但不确定是否能真实反映实际网络错误。
  • 反对:MDN文档未提及CORS异常会为fetch抛出TypeError
  • 反对:fetch规范中提到:

换句话说,不透明过滤响应和不透明重定向过滤响应几乎无法与网络错误区分。

另外,能否通过CORS预检请求(或直接发送OPTIONS请求)检测不允许CORS的服务器是否可达?


回答

一、no-cors模式下的Promise状态判断

你的结论完全正确:

  • Opaque响应(CORS限制导致):fetch的Promise会成功resolve,但返回的响应是"不透明"的——你无法读取响应状态码、响应头或响应体,仅能通过response.type === 'opaque'识别。这就是文档中所说的"静默失败",不会抛出任何错误。
  • 网络错误:包括DNS解析失败、连接超时、服务器拒绝连接、防火墙拦截等网络层面的问题,此时fetch的Promise会直接reject,并抛出TypeError。

关于规范中提到的"几乎无法区分",是指你无法从响应内容判断opaque响应的具体原因(比如是服务器返回了200但被CORS过滤,还是返回了404但被过滤),但Promise的状态是明确区分网络错误和CORS限制的:reject对应网络不可达,resolve对应请求已发送(无论服务器是否允许CORS)。

二、关于OPTIONS请求检测可达性的可行性

不能通过CORS预检请求或直接发送OPTIONS请求实现更准确的可达性检测,逻辑和no-cors模式的普通请求一致:

  • 若服务器不可达:OPTIONS请求会触发网络错误,Promise reject
  • 若服务器可达但不允许CORS:浏览器会拦截响应并返回opaque响应,Promise resolve,但你无法读取任何响应细节
  • 若服务器可达且允许CORS:你能正常读取响应状态码等信息,Promise resolve

本质上,用OPTIONS请求和用no-cors的GET/HEAD请求检测可达性的效果完全相同——只要Promise resolve,就说明网络层面能到达目标服务器;Promise reject则说明不可达。无需特意使用OPTIONS请求。


内容的提问来源于stack exchange,提问作者Rafael Emshoff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:20:33