在 iOS 上调用“fetch”时出现 Javascript“TypeError:cancelled”错误

Posted

技术标签:

【中文标题】在 iOS 上调用“fetch”时出现 Javascript“TypeError:cancelled”错误【英文标题】:Javascript "TypeError: cancelled" error when calling "fetch" on iOS 【发布时间】:2019-09-08 08:11:29 【问题描述】:

我正在使用 Sentry 记录 JS 客户端错误,并且有很多 TypeError: cancelled 错误。它只发生在 ios 上。我在谷歌上找不到任何东西。这是本机 javascript 错误还是其他什么?什么意思?

我在其他语言中也遇到类似错误,例如 취소됨Abgebrochencancelado。这告诉我错误不是由我的代码引发的。

【问题讨论】:

我在我的 Sentry 设置中看到了同样的情况,并且到目前为止它仅限于 iOS 12.2 和移动版 Safari 12.1。不包括堆栈跟踪,所以它非常神秘。我不确定问题是什么,也没有在相关搜索结果中看到任何内容。错误消息的“已取消”部分让我相信这可能与承诺或获取有关。 您是否正在向不允许 CORS 的站点发送 CORS 请求? @Aplet123 它适用于大约 97% 的用户,包括 iOS 用户。也许它与带有广告拦截器的越狱手机等有关。 我们在 Sentry 日志中遇到了同样的问题。从 IOS 11 开始有一个 CORS 问题。我们通过这种方式解决了一个问题***.com/a/52004250 @AntonAntonov 感谢您的链接,CORS 问题很有可能,但我的请求没有任何标题 【参考方案1】:

令人沮丧对吧?

最近我们的团队遇到了同样的错误。这是我们案例中发生的事情。当页面加载时,刷新按钮变为十字按钮,现在如果在此页面加载期间某些 api 请求正在进行并且用户单击此十字按钮,则 iOS chrome/safari 会引发此错误。对于同样的情况,Firefox 浏览器会抛出 TypeError: NetworkError when attempting to fetch resource,而 chrome 浏览器会抛出 TypeError: Failed to fetch

这并不是我们真正应该担心的问题,因此我们决定使用 sentry 的 ignoreErrors 属性让 sentry 忽略此错误。

Sentry.init(
  dsn: "sentry_dsn",
  ignoreErrors: [
    'TypeError: Failed to fetch',
    'TypeError: NetworkError when attempting to fetch resource.',
    'TypeError: Cancelled'
  ],
);

注意: CORS错误也会导致无法获取,请注意这一点。 我们还决定使用 sentry 的 beforeSend 回调忽略 statusCode 介于 400 到 426 之间的错误。

我们花了几天时间试图找出这个错误。希望这对某人有所帮助。

谢谢

另外, 这最初写在这里:https://forum.sentry.io/t/typeerror-failed-to-fetch-reported-over-and-overe/8447/2

【讨论】:

cancelled 应该小写吗?因为目前这对我不起作用。 是的@FernandoRojo 它应该小写 参见***.com/questions/49343024/…中的类似错误【参考方案2】:

如果您使用的是fetch API,那么 iOS 11.1-12 中的 AbortControllerAbortSignal 可能会出现问题,它们只会在有人尝试中止获取请求时触发(这就是为什么它不一定会影响所有 iOS 用户,解释了不一致)。

详细地说,iOS 11.1-12 在 DOM 中定义了 AbortControllerAbortSignal,但它们是一个存根 - see here。因此,如果您尝试在

鉴于它是 TypeError 而不是 AbortError,问题似乎在于 AbortController 没有正确/完全定义。

编辑: 进一步阅读似乎还表明,iOS 中失败的fetches 会引发TypeError 错误,即使对于诸如阻塞提取之类的事情也是如此。如上所述,问题可能在于安装了任何广告拦截器(例如,在越狱的 iPhone 上)或 CORS 问题,然后 iOS 会抛出 TypeError - Webkit BugZilla discussion。因此,专注于错误类型可能会导致您走上错误的道路。

【讨论】:

【参考方案3】:

我必须给 Sentry 发送电子邮件才能在此处获取错误。

事实证明,我在extra 字段中发送了错误,而ignoreErrors 属性没有说明这一点。我是这样解决的:

const ignoreErrors = [
      'TypeError: NetworkError when attempting to fetch resource.',
      'TypeError: cancelled',
      'TypeError: Cancelled',
      'message: cancelled',
      'cancelled',
]

Sentry.init(
    async beforeSend(event) 
      // this is using typescript, but change it as you need
      const message = (event?.extra as
        | undefined
        | 
            error?:  message?: string 
          )?.error?.message?.toLowerCase()

      if (message && ignoreErrors.includes(message)) 
        return null // don't send
      
      return event
    ,
    ignoreErrors,
)

【讨论】:

你知道是什么原因导致“消息:已取消”和“已取消”吗?你有信心可以忽略它们吗? 已经有一段时间了,所以我希望我有一个更好的答案。但我认为这只是网络问题,可以忽略。不过我会对此进行一些研究。【参考方案4】:

根据 WHATWG 标准:https://html.spec.whatwg.org/multipage/browsing-the-web.html#aborting-a-document-load,在中止文档(关闭或导航离开)时将取消获取请求。显然浏览器的行为有所不同,所以我制作了一个工具来测试浏览器的行为,如果有帮助的话:https://request-cancellation-test.vercel.app (code)。

以下是常用浏览器的测试结果:

Field Chrome 95 Safari 14 iOS Safari 14 Firefox 94
.toString() TypeError: Failed to fetch TypeError: cancelled TypeError: cancelled TypeError: NetworkError when attempting to fetch resource.
.name TypeError TypeError TypeError TypeError
.message Failed to fetch cancelled cancelled NetworkError when attempting to fetch resource.
.stack TypeError: Failed to fetch at ...

【讨论】:

以上是关于在 iOS 上调用“fetch”时出现 Javascript“TypeError:cancelled”错误的主要内容,如果未能解决你的问题,请参考以下文章

通过 Office Scripts Fetch 调用 API 时出现 CORS 问题

Javas Audio Clips 在频繁播放哔声时出现问题

错误:使用 Fetch API 向第三方 API 发出 GET 请求时出现“TypeError:无法获取”

运行基本 git 命令(如“git fetch”)时出现 kex_exchange_identification 错误

将oci_fetch_assoc数据转换为json时出现问题

Fullcalendar.io在将事件属性解析为函数时出现问题