我在我的React应用中使用fetch API。该应用程序部署在服务器上,运行正常。我多次测试了它。但是,突然应用程序停止工作,我不知道为什么。问题是,当我发送get
请求时,我收到服务器的有效响应,但fetch API正在捕获异常并显示TypeError: failed to fetch
。我甚至没有对代码进行任何更改,这是所有React组件的问题。
我收到了有效回复。
但同时也会出现此错误。
fetch(url)
.then(res => res.json())
.then(data => {
// do something with data
})
.catch(rejected => {
console.log(rejected);
});
当我删除credentials: "include"
时,它适用于localhost,但不适用于服务器。
我尝试了在StackOverflow和GitHub上给出的每个解决方案,但这对我来说不合适。
答案 0 :(得分:13)
问题可能在于您从后端收到的回复。如果它在服务器上正常工作,那么问题可能在于响应头。 检查响应标头中的 Access-Control-Allow-Origin (ACAO)。通常,当响应标头的ACAO和请求的来源不匹配时,即使在收到响应后,react的fetch API也将无法获取。
答案 1 :(得分:13)
我知道这个问题可能有特定于 React 的原因,但它首先出现在“Typeerror: Failed to fetch”的搜索结果中,我想在这里列出所有可能的原因。
Fetch 规范列出了您从 Fetch API 抛出 TypeError 的次数:https://fetch.spec.whatwg.org/#fetch-api
截至 2021 年 1 月的相关段落如下。这些是正文的摘录。
4.6 HTTP 网络获取
<块引用>要使用带有可选凭据标志的请求执行 HTTP 网络提取,请运行以下步骤:
...
16. 并行运行这些步骤:
...
2.如果中止,则:
...
3. 否则,如果流可读,则错误流为 TypeError。
要将名称/值名称/值对附加到 Headers 对象(标头),请运行以下步骤:
使用给定的对象对象填充标题对象标题:
<块引用>要使用给定的对象对象填充 Headers 对象标题,请运行以下步骤:
方法步骤有时会抛出 TypeError:
<块引用>delete(name) 方法步骤是:
get(name) 方法步骤是:
has(name) 方法步骤是:
set(name, value)方法步骤为:
要从对象中提取主体和 Content-Type
值,使用可选的布尔值 keepalive(默认为 false),请运行以下步骤:
...
5. 开启对象:
...
可读流
如果 keepalive 为真,则抛出 TypeError。
如果对象受到干扰或锁定,则抛出 TypeError。
在“Body mixin”部分,如果您使用 FormData,有几种方法可以抛出 TypeError。我没有在这里列出它们,因为它会使这个答案很长。相关段落:https://fetch.spec.whatwg.org/#body-mixin
在“请求类”部分中,新的 Request(input, init) 构造函数是潜在类型错误的雷区:
<块引用>新的Request(input, init)构造器步骤为:
...
6. 如果输入是字符串,则:
...
2. 如果 parsedURL 失败,则抛出 TypeError。
3. 如果 parsedURL 包含凭据,则抛出 TypeError。
...
11. 如果 init["window"] 存在且非空,则抛出 TypeError。
...
15.如果init["referrer"存在,则:
...
1.让referrer为init["referrer"].
2. 如果referrer为空字符串,则设置request的referrer为“no-referrer”。
3. 否则:
1.让parsedReferrer为baseURL解析referrer的结果。
2. 如果parsedReferrer失败,则抛出TypeError。
...
18.如果模式是“导航”,则抛出一个TypeError。
...
23.如果请求的缓存模式是“only-if-cached”并且请求的模式不是“same-origin”,那么抛出一个TypeError。
...
27.如果init["method"]存在,则:
...
2.如果method不是方法或者method是禁止方法,则抛出TypeError。
...
32.如果这个请求的模式是“no-cors”,则:
1. 如果这个请求的方法不是 CORS 安全列表方法,则抛出 TypeError。
...
35. 如果 init["body"] 存在且为非空或 inputBody 为非空,并且请求的方法为 GET
或 HEAD
,则抛出 TypeError。
...
38.如果body为非空且body的源为null,则:
1.如果这个请求的模式既不是“同源”也不是“cors”,那么抛出一个TypeError。
...
39. 如果 inputBody 是 body 并且 input 被干扰或锁定,则抛出 TypeError。
clone() 方法步骤是:
在响应类中:
<块引用>新的Response(body, init)构造器步骤是:
...
2. 如果 init["statusText"] 与原因短语标记产生不匹配,则抛出 TypeError。
...
8.如果body为非空,则:
1. 如果 init["status"] 是 null body 状态,则抛出 TypeError。
...
静态redirect(url, status)方法步骤为:
...
2. 如果 parsedURL 失败,则抛出 TypeError。
clone() 方法步骤是:
在“获取方法”部分
<块引用>fetch(input, init)方法步骤为:
...
9. 并行运行以下:
要处理响应响应,请运行以下子步骤:
...
3. 如果响应是网络错误,则以 TypeError 拒绝 p 并终止这些子步骤。
除了这些潜在问题之外,还有一些特定于浏览器的行为可能会引发 TypeError。例如,如果您将 keepalive 设置为 true 并且有效负载 > 64 KB,您将在 Chrome 上收到 TypeError,但相同的请求可以在 Firefox 中工作。这些行为未记录在规范中,但您可以通过谷歌搜索找到有关您在 fetch 中设置的每个选项的限制的信息。
答案 2 :(得分:3)
我知道这是一个相对较旧的职位,但是,我想分享对我有用的内容: 我只是在URL中的“ localhost”之前输入“ http://”。希望对别人有帮助。
答案 3 :(得分:2)
请注意,您的代码中存在一个不相关的问题,但稍后会引起您的注意:您应该return res.json()
或者您不会发现JSON解析或您自己的函数处理数据中发生的任何错误。
返回错误:无法拥有成功请求的TypeError: failed to fetch
。您可能有另一个请求(检查您的&#34;网络&#34;面板以查看所有这些请求)中断并导致记录此错误。此外,也许,检查&#34;保留日志&#34;确保面板不会被任何不正确的重定向清除。有时我碰巧有一个持久的&#34;控制台&#34;面板和清除的网络&#34;导致我在控制台中出错的面板实际上与可见请求无关。你应该检查一下。
或者你(但那会很恶毒)实际上在你的最终console.log('TypeError: failed to fetch')
中有一个硬编码的.catch
;并且错误在你的.then()
中实际存在但是它已经存在很难相信。
答案 4 :(得分:1)
如果要在本地主机服务器上调用访存,请使用非SSL协议,除非您具有本地主机的有效证书。对于无效或自签名证书,尤其是在本地主机上,获取将失败。
答案 5 :(得分:1)
就我而言,我在使用 jsfiddle 或 stackblitz 等在线 JS 工具时遇到了“TypeError”,问题是我的 url 是 http 而不是 https。
答案 6 :(得分:0)
我有一个类似的问题,由于我是新手,因此有一些事实可供人们评论:
我正在以这种方式向Google工作表发送表单数据(scriptURL为https://script.google.com/macros/s/AKfy ..., showSuccess()显示的是简单图像):
fetch(scriptURL, {method: 'POST', body: new FormData(form)})
.then(response => showSuccess())
.catch(error => alert('Error! ' + error.message))
在Edge中执行时,我的HTML没有显示错误,并且“网络”标签报告了这3个请求:
在Chrome中执行的我的HTML(index.htm)显示无法提取错误,并且“网络”标签报告了这2个请求:
第二列的值是 blocked:other ,并且“控制台”选项卡中也存在错误:
获取https://script.googleusercontent.com/macros/echo?user_content_key=D-ABF ... 净:: ERR_BLOCKED_BY_CLIENT
为了暂停已安装的Chrome扩展程序,我在隐身窗口中执行了我的代码,没有错误消息,并且“网络”标签报告了这2个请求:
我的猜测是,某些内容(扩展名?)阻止Chrome浏览器读取请求的答案(GET请求被阻止)。
答案 7 :(得分:0)
在幕后,XHR 客户端发送一个 HTTPOPTIONS 请求,称为 pre-flight,以查找某些安全权限标头,称为 CORS Allow 标头。如果未找到所需的标头(因为您可能没有必要的权限),则结果为 TypeError,因为它实际上并未尝试发送您的 POST/GET 请求。您可以在浏览器控制台中观察这种行为:看起来浏览器向同一位置发出了两个请求,首先是 HTTP 方法:OPTIONS。