简体   繁体   English

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

[英]Fetch throws “TypeError: Failed to fetch” for successful, same-origin request

We have been encountering inconsistent client errors with a single-page JavaScript application making fetch requests.我们一直在使用发出获取请求的单页 JavaScript 应用程序遇到不一致的客户端错误。 Of note, they are all same-origin requests.值得注意的是,它们都是同源请求。

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

Around 5% of the promises are rejecting with the following error despite the server and the browser receiving a 200 OK response:尽管服务器和浏览器收到200 OK响应,但仍有大约 5% 的承诺被拒绝并出现以下错误:

TypeError: Failed to fetch

I'm stumped... All of my searches lead to discussions about CORS errors.我很难过......我所有的搜索都导致了关于 CORS 错误的讨论。 That doesn't seem to apply given these are all same-origin requests.鉴于这些都是同源请求,这似乎并不适用。 What is causing the fetch to throw the TypeError ?是什么导致 fetch 抛出TypeError

I can confirm using the Network tab in Chrome DevTools that the fetch request completes with a 200 OK response and valid JSON.我可以使用 Chrome DevTools 中的 Network 选项卡确认获取请求以200 OK响应和有效 JSON 完成。 I can also confirm that the URLs are same-origin.我还可以确认这些 URL 是同源的。 I can also confirm that there are no CORS pre-flight requests.我还可以确认没有 CORS 飞行前请求。 I have reproduced this issue on Chrome 66 and Safari 11.1.我已经在 Chrome 66 和 Safari 11.1 上重现了这个问题。 However, we've received a stream of error reports from a mix of Chrome and Safari versions, both desktop and mobile.但是,我们收到了一系列来自 Chrome 和 Safari 版本(桌面版和移动版)的错误报告。


EDIT:编辑:

This does not appear to be a duplicate of the linked question as we are not sending CORS requests, not setting mode: "no-cors" , and not setting the Access-Control-Allow-Origin header.这似乎不是链接问题的重复,因为我们没有发送 CORS 请求,没有设置mode: "no-cors" ,也没有设置Access-Control-Allow-Origin标头。

Additionally, I re-ran tests with the mode: 'same-origin' option set explicitly.此外,我使用mode: 'same-origin'选项显式设置重新运行测试。 The requests are (still) successful;请求(仍然)成功; however, we (still) receive the intermittent TypeError .然而,我们(仍然)收到间歇性的TypeError

I know that this is an old issue, but after searching the entire evening I want to share my findings so you can spend your time better.我知道这是一个老问题,但在搜索了整个晚上之后,我想分享我的发现,这样你就可以更好地度过你的时间。

My web app also worked well for most users but from time to time visitors received the error mentioned in the question.我的网络应用程序也适用于大多数用户,但有时访问者会收到问题中提到的错误。 I'm not using any complicated infrastructure (reverse proxy etc.) setup nor do I communicate with services on a different domain/protocol/port.我没有使用任何复杂的基础设施(反向代理等)设置,也没有与不同域/协议/端口上的服务进行通信。 I'm just sending a POST request to a PHP-File on the same server where the React app is served from.我只是向提供 React 应用程序的同一服务器上的 PHP 文件发送 POST 请求。

The short answer: My problem was that I've sent the request to the backend by using an absolute URL, like https://my-fancy-domain.com/funky_service.php .简短的回答:我的问题是我已经使用绝对 URL 将请求发送到后端,例如https://my-fancy-domain.com/funky_service.php After changing this to a relative path like /funky-service.php the issue was gone.将其更改为像/funky-service.php这样的相对路径/funky-service.php ,问题就消失了。

My explanation: Most users come to the site without www in the URL, but some users actually do type this part in their address bars ( www.my-fancy... ).我的解释:大多数用户访问该网站时 URL 中没有 www,但有些用户确实在他们的地址栏中输入了这一部分( www.my-fancy... )。 It turned out that the www is part of the origin , so when these users submit the form and send post requests to https://my-fancy... it's technically another origin.原来www 是 origin 的一部分,所以当这些用户提交表单并将 post 请求发送到 https://my-fancy ......从技术上讲,它是另一个起源。 This is why the browser expects CORS headers and sometimes even sends an OPTIONS preflight request.这就是为什么浏览器需要 CORS 标头,有时甚至会发送 OPTIONS 预检请求的原因。 When you use a relative path in your JavaScript-Code the post request will also include the www-part (uses the origin from the address bar) -> same-origin -> no CORS hassle.当您在 JavaScript 代码中使用相对路径时,发布请求还将包括 www 部分(使用地址栏的来源)-> 同源-> 没有 CORS 麻烦。 As it only affects visitors that come with the www to your site it also explains the fact that it worked for most users even with the absolute URL.由于它只影响带有 www 到您网站的访问者,因此它也解释了一个事实,即即使使用绝对 URL,它也适用于大多数用户。

Also important to know: The request fails in the browser/ JavaScript-Code but is actually sent to the backend (very ugly!).同样重要的是:请求在浏览器/JavaScript 代码中失败,但实际上被发送到后端(非常难看!)。

Let me know if you need more information.如果您需要更多信息,请与我们联系。 Actually, it is very simple but hard to explain (and to find)实际上,这很简单但很难解释(和找到)

The issue could be with the response you are receiving from back-end.问题可能与您从后端收到的响应有关。 If it was working fine on the server then the problem could be with the response headers.如果它在服务器上工作正常,那么问题可能出在响应标头上。 Check the Access-Control-Allow-Origin (ACAO) in the response headers.检查响应标头中的 Access-Control-Allow-Origin (ACAO)。 Usually react's fetch API will throw fail to fetch even after receiving response when the response headers' ACAO and the origin of request won't match.通常,当响应头的 ACAO 和请求的来源不匹配时,即使在收到响应后,react 的 fetch API 也会抛出失败。

Ref: Getting "TypeError: failed to fetch" when the request hasn't actually failed参考: 当请求实际上没有失败时,得到“TypeError: failed to fetch”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 即使使用“同源”凭据,Javascript Fetch 也不会在请求标头中传递 Cookie - Javascript Fetch Not passing Cookies in the Request Headers, even with 'same-origin' credentials 是什么导致无法在“ServiceWorkerGlobalScope”上执行“fetch”:“only-if-cached”只能设置为“same-origin”模式错误? - What causes a Failed to execute 'fetch' on 'ServiceWorkerGlobalScope': 'only-if-cached' can be set only with 'same-origin' mode error? 使用javascript提取,在no-cors,cors和same-origin模式之间有所不同 - Fetch in javascript, different between mode no-cors, cors and same-origin JavaScript的Fetch API的“同源”和“无源”之间有什么区别? - What's the difference between “same-origin” and “no-cors” for JavaScript's Fetch API? CORS 阻塞 javascript 同源获取请求 - CORS blocking javascript fetch request with same origin 在 Service Worker 中请求 formData - TypeError:无法获取 - Request formData in Service Worker - TypeError: Failed to fetch React Native TypeError:网络请求失败,fetch() - React native TypeError: Network request failed with fetch() TypeError 执行 GET 请求时获取失败 - TypeError Failed to fetch when doing GET request Chrome将Origin标头添加到同源请求中 - Chrome adding Origin header to same-origin request 同源政策 - Same-origin policy
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM