对于成功的同源请求,Fetch 会抛出“TypeError: Failed to fetch”
Posted
技术标签:
【中文标题】对于成功的同源请求,Fetch 会抛出“TypeError: Failed to fetch”【英文标题】:Fetch throws "TypeError: Failed to fetch" for successful, same-origin request 【发布时间】:2018-10-29 07:59:27 【问题描述】:在单页 javascript 应用程序发出提取请求时,我们遇到了不一致的客户端错误。值得注意的是,它们都是 same-origin 请求。
let request = new Request(url, options);
...
window.fetch(request)
.then(response => response.json())
.then(data => ...)
.catch(error => ...)
尽管服务器和浏览器收到了200 OK
响应,但仍有大约 5% 的 Promise 被拒绝并出现以下错误:
TypeError: Failed to fetch
我很难过...我所有的搜索都会引发关于 CORS 错误的讨论。鉴于这些都是同源请求,这似乎并不适用。是什么导致 fetch 抛出 TypeError
?
我可以使用 Chrome DevTools 中的“网络”选项卡确认获取请求已完成,并带有 200 OK
响应和有效的 JSON。我还可以确认 URL 是同源的。我还可以确认没有 CORS 飞行前请求。我已经在 Chrome 66 和 Safari 11.1 上重现了这个问题。但是,我们收到了来自桌面版和移动版 Chrome 和 Safari 混合版本的一系列错误报告。
编辑:
这似乎不是链接问题的重复,因为我们不发送 CORS 请求,不设置mode: "no-cors"
,不 em> 设置Access-Control-Allow-Origin
标头。
此外,我使用明确设置的mode: 'same-origin'
选项重新运行测试。请求(仍然)成功;但是,我们(仍然)收到间歇性的TypeError
。
【问题讨论】:
您在options
中使用mode: "no-cors"
吗?见***.com/questions/42754388/…
@Barmar 我确实不设置mode
选项。看起来默认的mode
是cors
(developer.mozilla.org/en-US/docs/Web/API/Request/mode)。不确定这在同源请求的上下文中意味着什么。但是,我可以通过显式使用mode: same-origin
重新测试和更新线程。
Uncaught (in promise) TypeError: Failed to fetch and Cors error的可能重复
@Mr.White 我通读了那个问题......接受的答案谈到了 CORS 标头和飞行前请求。这些不会发生在我的同源请求中。此外,该问题的 cmets 对该问题有 real 的答案:“我认为,如果您从请求中删除访问控制标头并且不添加模式,您的所有问题都会消失:'不接受请求”。我已经确认这就是我的请求的构造方式。
我找不到任何其他不涉及该选项的错误解释。
【参考方案1】:
我知道这是一个老问题,但是在搜索了整个晚上后,我想分享我的发现,以便您可以更好地度过时间。
我的网络应用程序对大多数用户来说也运行良好,但有时访问者会收到问题中提到的错误。我没有使用任何复杂的基础设施(反向代理等)设置,也没有与不同域/协议/端口上的服务进行通信。我只是向提供 React 应用程序的同一服务器上的 php 文件发送 POST 请求。
简短的回答:我的问题是我使用绝对 URL 将请求发送到后端,例如 https://my-fancy-domain.com/funky_service.php
。将其更改为 /funky-service.php
之类的相对路径后,问题就消失了。
我的解释:大多数用户访问该站点时 URL 中没有 www,但有些用户实际上确实在地址栏中输入了这部分 (www.my-fancy...
)。原来,www 是来源的一部分,所以当这些用户提交表单并向 https://my-fancy 发送帖子请求时……从技术上讲,它是另一个来源。这就是为什么浏览器需要 CORS 标头,有时甚至会发送一个 OPTIONS 预检请求。当您在 JavaScript 代码中使用相对路径时,发布请求还将包括 www 部分(使用地址栏中的来源)-> 同源-> 没有 CORS 麻烦。由于它只影响带有 www 访问您网站的访问者,因此它也说明了即使使用绝对 URL,它也适用于大多数用户。
同样重要的是要知道:请求在浏览器/JavaScript 代码中失败,但实际上被发送到后端(非常丑陋!)。
如果您需要更多信息,请告诉我。实际上,它很简单,但很难解释(也很难找到)
【讨论】:
【参考方案2】:问题可能与您从后端收到的响应有关。如果它在服务器上运行良好,那么问题可能出在响应标头上。检查响应标头中的 Access-Control-Allow-Origin (ACAO)。通常react的fetch API在response headers的ACAO和request的来源不匹配的情况下,即使收到response也会抛出fail to fetch。
参考:Getting "TypeError: failed to fetch" when the request hasn't actually failed
【讨论】:
是的,CORS 应用程序的故障排除步骤非常好。在我们的例子中,这是一个同源请求。 你浏览评论中的链接了吗?以上是关于对于成功的同源请求,Fetch 会抛出“TypeError: Failed to fetch”的主要内容,如果未能解决你的问题,请参考以下文章
android的React Native fetch()网络请求失败?
React Native fetch() 在 Android 7 上抛出“网络请求失败”,但在 Android 6 上运行良好
React Fetch 到 Laravel API 创建新会话