在 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 错误还是其他什么?什么意思?
我在其他语言中也遇到类似错误,例如 취소됨
、Abgebrochen
和 cancelado
。这告诉我错误不是由我的代码引发的。
【问题讨论】:
我在我的 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 中的 AbortController
和 AbortSignal
可能会出现问题,它们只会在有人尝试中止获取请求时触发(这就是为什么它不一定会影响所有 iOS 用户,解释了不一致)。
详细地说,iOS 11.1-12 在 DOM 中定义了 AbortController
和 AbortSignal
,但它们是一个存根 - 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 错误