对于成功的同源请求,Fetch抛出“TypeError:Failed to fetch”

时间:2018-05-18 20:20:57

标签: javascript fetch

我们遇到了与单页JavaScript应用程序进行获取请求不一致的客户端错误。值得注意的是,它们都是同源请求。

let request = new Request(url, options);
...
window.fetch(request)
  .then(response => response.json())
  .then(data => ...)
  .catch(error => ...)

尽管服务器和浏览器收到200 OK响应,但仍有大约5%的承诺拒绝并出现以下错误:

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"没有设置Access-Control-Allow-Origin标题。

此外,我重新运行了明确设置mode: 'same-origin'选项的测试。请求(仍然)成功;但是,我们(仍然)收到间歇TypeError

2 个答案:

答案 0 :(得分:4)

我知道这是一个老问题,但在搜索了一整个晚上之后,我想分享我的发现,以便您可以更好地利用时间。

我的网络应用程序也适用于大多数用户,但有时访问者会收到问题中提到的错误。我没有使用任何复杂的基础设施(反向代理等)设置,也没有与不同域/协议/端口上的服务进行通信。我只是向提供 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 代码中失败,但实际上被发送到后端(非常难看!)。

如果您需要更多信息,请告诉我。其实很简单,但是很难解释(和找到)

答案 1 :(得分:-1)

问题可能与您从后端收到的响应有关。如果它在服务器上工作正常,那么问题可能出在响应标头上。检查响应标头中的 Access-Control-Allow-Origin (ACAO)。通常,当响应头的 ACAO 和请求的来源不匹配时,react 的 fetch API 即使在收到响应后也会抛出 fail to fetch。

参考:Getting "TypeError: failed to fetch" when the request hasn't actually failed