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

启用application/octet-stream类型API后小部分用户报Failed to fetch

问题背景

现有两套通过功能开关切换的API版本:

  • 旧版本返回application/json类型响应
  • 新版本返回application/octet-stream类型响应

切换到新版本API后,小部分用户调用接口时收到failed to fetch报错,已确认信息如下:

  • 调用成功与失败的用户,浏览器版本、操作系统完全一致,无环境版本差异
  • 两个版本API使用完全相同的请求配置,配置内容如下:
{
  "headers": {
    "accept": "*/*",
    "accept-language": "en-US,en;q=0.9",
    "authorization": "...",
    "content-type": "application/json",
    "sec-ch-ua": "\".Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"103\", \"Chromium\";v=\"103\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "Windows 10",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-site"
  },
  "referrer": "...",
  "referrerPolicy": "no-referrer-when-downgrade",
  "body": "...",
  "method": "POST",
  "mode": "cors",
  "credentials": "include"
}
  • 报错表现和无网络连接类错误一致,但服务端日志显示已收到所有报错用户的请求,且同域下其他API均可正常响应,捕获到的错误内容如下:
{
  "error": {
    "message": "Failed to fetch",
    "name": "TypeError",
    "stack": "TypeError: Failed to fetch\n (...the chunks it failed at)"
  }
}

需要排查的核心方向:问题诱因、是否存在遗漏的请求/响应头配置、是否为企业防火墙等网络中间件拦截导致。

根因分析(按出现概率从高到低排序)

Failed to fetch是浏览器Fetch API抛出的网络层通用错误,触发条件是浏览器接收完整响应前连接被异常中断,或响应违反浏览器安全策略。结合「服务端已收到请求、同域其他接口正常、仅切到二进制流接口后小部分用户报错」的特征,排除基础网络断连、全量CORS配置错误类问题,可能原因如下:

  • 最高概率:网络中间件拦截/截断二进制响应
    切换为application/octet-stream后,响应为二进制流,企业防火墙、上网行为管理设备、本地杀毒软件的网页防护模块,默认会对非文本类HTTP响应做内容扫描:如果响应体大小超过设备单请求扫描阈值、扫描过程超时、或二进制内容命中设备的特征规则,设备会直接重置TCP连接,不会将完整响应返回给浏览器,最终触发该错误。
    这类问题的典型特征和描述完全吻合:仅小部分处于对应企业网络、开启了对应防护软件的用户命中,服务端可正常接收请求、甚至已完成响应发送,但中间链路主动掐断连接,浏览器无法收到完整响应。
    验证方式非常直接:让报错用户切换手机热点(绕过企业网络、退出本地安全防护软件)后重新调用接口,如果能正常返回即可确认是中间件问题。
  • 次高概率:响应头配置缺失触发浏览器安全拦截
    请求是same-site跨子域请求,且携带了credentials: "include",返回二进制流时如果漏配以下头,部分场景下浏览器会直接拦截响应,抛出和网络错误完全一致的异常:
    1. 确认新版本接口的Access-Control-Allow-Origin不能为通配符*,必须精确匹配请求源,同时必须携带Access-Control-Allow-Credentials: true。很多网关按路由规则单独配头,切流后新版本路由很容易漏带这两个旧接口已经配置的头。
    2. 二进制流场景必须明确返回Content-Disposition头:如果是触发下载就配置attachment; filename="自定义文件名",如果是前端逻辑内读取处理就配置inline,不要让浏览器自动推断内容处理方式,部分Chrome版本在推断octet-stream处理逻辑时如果和页面安全策略冲突,会直接中断请求。
    3. 检查Content-Length头的值和实际返回的响应体大小是否完全一致,如果服务端分块传输二进制流时长度计算错误,浏览器读取到不完整响应体也会抛出fetch错误。
  • 低概率:压缩配置不匹配
    该场景概率极低,但确实存在:部分反向代理默认对application/octet-stream类型响应关闭压缩,或开启压缩后没有正确返回Content-Encoding头,浏览器拿到压缩内容后无法正常解码,就会中断连接报错。不需要主动修改请求侧的accept-encoding配置(浏览器会自动携带该头),只需要对比正常响应和异常场景的响应头,确认Content-Encoding声明和实际响应内容编码一致即可。
修复建议
  • 优先通过热点切换验证是否为中间件问题:如果确认是用户侧网络管控导致,可针对这类场景开启TLS 1.3加密,减少中间件解密扫描响应内容的概率,这类问题本质是用户侧管控规则导致,服务端无法100%兼容所有管控策略,可针对报错用户提供明确的绕过指引。
  • 逐行核对新版本接口的CORS相关头、Content-Disposition、Content-Length配置,确保和旧版JSON接口的安全类响应头完全一致,避免切流时路由规则变更导致头丢失。
  • 检查网关层对octet-stream响应的压缩规则,确保编码声明和实际内容匹配。

内容的提问来源于stack exchange,提问作者Kenneth Truong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:01:07