当请求实际上没有失败时,获取"TypeError:无法获取"

Ama*_*ria 25 javascript get fetch-api

我在我的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);
});
Run Code Online (Sandbox Code Playgroud)

当我删除时credentials: "include",它适用于localhost,但不适用于服务器.

我尝试了在StackOverflow和GitHub上给出的每个解决方案,但它只是不适合我.

yug*_*tar 19

问题可能在于您从后端收到的响应.如果它在服务器上正常工作,那么问题可能在于响应头.检查响应头中的Access-Control-Allow-Origin(ACAO).通常,当响应头的ACAO和请求的起源不匹配时,即使在接收到响应之后,react的fetch API仍将无法获取.

  • 你能详细说明这个答案吗?我是 node.js 和后端环境的新手。所以,我一个字都听不懂。PS一个`代码`示例会很棒:) (3认同)
  • 可以在https://medium.com/@baphemot/understanding-cors-18ad6b478e2b中找到扩展的说明。 (2认同)
  • 我正在测试对丢失会话的响应并收到此错误。REST 调用从不同的服务器发回重定向,并且如果违反引用策略:跨源时严格源。这是来自 Fetch API 的糟糕错误响应。 (2认同)

Gre*_*ray 15

我知道这个问题可能有特定于 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 对象(标头),请运行以下步骤:

  1. 标准化值。
  2. 如果名称不是名称或值不是值,则抛出 TypeError。
  3. 如果 headers 的守卫是“不可变的”,那么抛出一个 TypeError。

使用给定的对象对象填充 Headers 对象标题:

要使用给定的对象对象填充 Headers 对象标题,请运行以下步骤:

  1. 如果 object 是一个序列,则对于 object 中的每个标头:
    1. 如果 header 不包含正好两个项目,则抛出 TypeError。

方法步骤有时会抛出 TypeError:

delete(name) 方法步骤是:

  1. 如果 name 不是名称,则抛出 TypeError。
  2. 如果这个守卫是“不可变的”,那么抛出一个类型错误。

get(name) 方法步骤是:

  1. 如果 name 不是名称,则抛出 TypeError。
  2. 返回从 t​​his 的标题列表中获取 name 的结果。

has(name) 方法步骤是:

  1. 如果 name 不是名称,则抛出 TypeError。

set(name, value) 方法步骤是:

  1. 标准化值。
  2. 如果名称不是名称或值不是值,则抛出 TypeError。
  3. 如果这个守卫是“不可变的”,那么抛出一个类型错误。

要从对象中提取主体和Content-Type值,使用可选的布尔值 keepalive(默认为 false),请运行以下步骤:
...
5. 打开对象:
...
ReadableStream
如果 keepalive 为 true,则抛出 TypeError。
如果对象受到干扰或锁定,则抛出 TypeError。

在“Body mixin”部分,如果您使用 FormData,有几种方法可以抛出 TypeError。我没有在这里列出它们,因为它会使这个答案很长。相关段落:https : //fetch.spec.whatwg.org/#body-mixin

在“请求类”部分中,新的 Request(input, init) 构造函数是潜在类型错误的雷区:

new Request(input, init) 构造器步骤是:
...
6. 如果输入是字符串,则:
...
2. 如果 parsedURL 失败,则抛出 TypeError。
3. 如果 parsedURL 包含凭据,则抛出 TypeError。
...
11. 如果 init["window"] 存在且非空,则抛出 TypeError。
...
15. 如果 init["referrer" 存在,则:
...
1. 让referrer 为 init["referrer"]。
2. 如果referrer 为空字符串,则将请求的referrer 设置为“no-referrer”。
3. 否则:
1. 将parsedReferrer 设为使用baseURL 解析referrer 的结果。
2. 如果parsedReferrer 失败,则抛出TypeError。 18.如果模式是“导航”,
...

...
23. 如果请求的缓存模式是“only-if-cached”并且请求的模式不是“same-origin”,则抛出 TypeError。
...
27. 如果 init["method"] 存在,则:
...
2. 如果方法不是方法或方法是禁止方法,则抛出 TypeError。
...
32. 如果这个请求的模式是“no-cors”,那么:
1. 如果这个请求的方法不是 CORS-safelisted 方法,那么抛出一个 TypeError。
...
35. 如果 init["body"] 存在且非空或 inputBody 非空,并且请求的方法是GETor HEAD,则抛出 TypeError。 1.如果这个请求的模式既不是“同源”也不是“cors”,那么抛出一个TypeError。 ...
...
38。


39. 如果 inputBody 是 body 并且 input 被干扰或锁定,则抛出 TypeError。

clone() 方法步骤是:

  1. 如果这受到干扰或锁定,则抛出 TypeError。

在响应类中:

新的 Response(body, init) 构造器步骤是:
...
2. 如果 init["statusText"] 与原因短语标记产生不匹配,则抛出 TypeError。
...
8. 如果 body 为非空,则:
1. 如果 init["status"] 为 null body status,则抛出 TypeError。
...

静态redirect(url, status) 方法步骤是:
...
2. 如果parsedURL 失败,则抛出TypeError。

clone() 方法步骤是:

  1. 如果这受到干扰或锁定,则抛出 TypeError。

在“获取方法”部分

fetch(input, init) 方法步骤是:
...
9. 并行运行以下内容:
要处理响应的响应,请运行以下子步骤:
...
3. 如果响应是网络错误,则使用 TypeError 拒绝 p并终止这些子步骤。

除了这些潜在问题之外,还有一些特定于浏览器的行为可能会引发 TypeError。例如,如果您将 keepalive 设置为 true 并且有效负载 > 64 KB,您将在 Chrome 上收到 TypeError,但相同的请求可以在 Firefox 中工作。这些行为没有记录在规范中,但您可以通过谷歌搜索找到有关您在 fetch 中设置的每个选项的限制的信息。

  • @ADJenks 不。 [规范](https://heycam.github.io/webidl/#exceptiondef-typeerror) 没有指定附加到错误的注释应该是什么。因此,包含的消息(或缺少消息)取决于浏览器。 (2认同)

小智 8

请注意,您的代码中有一个不相关的问题,但稍后可能会困扰您:您应该return res.json() 或不会捕获 JSON 解析或您自己的函数处理数据中发生的任何错误。

回到您的错误:您无法TypeError: failed to fetch成功请求。您可能有另一个请求(检查您的“网络”面板以查看所有请求),该请求会中断并导致记录此错误。另外,也许检查“保留日志”以确保面板不会被任何不恰当的重定向清除。有时我碰巧有一个持久的“控制台”面板和一个清除的“网络”面板,这导致我在控制台中出现错误,这实际上与可见请求无关。你应该检查一下。

或者你(但这将是恶毒的)实际上console.log('TypeError: failed to fetch')在你的最后有一个硬编码.catch;)并且错误实际上在你的代码中.then(),但很难相信。

  • 实际上,我有同样的问题:网络显示 DELETE 请求成功,响应为 202,但 f"etch 请求在应用程序中出现“TypeError:无法获取”错误。并且外部休息调用上的响应标头显示“Access- Control-Allow-Origin" = *。可能与服务器上的 OPTIONS 支持有关? (2认同)

小智 8

如果您在本地主机服务器上调用 fetch,请使用非 SSL,除非您拥有有效的本地主机证书。获取将在无效或自签名证书上失败,尤其是在本地主机上。

  • 您能详细说明一下如何使用非 SSL 吗? (3认同)

小智 6

我知道这是一篇相对较旧的帖子,但是,我想分享对我有用的内容:我只是在 url 中的“localhost”之前输入了“http://”。希望它可以帮助某人。