当请求实际上没有失败时出现“TypeError: Failed to fetch”

新手上路,请多包涵

我在我的 React 应用程序中使用 fetch API 。该应用程序部署在服务器上并且运行良好。我测试了很多次。但是,应用程序突然停止工作,我不知道为什么。问题是当我发送 get 请求时,我收到了来自服务器的有效响应,但获取 API 也捕获了异常并显示 TypeError: Failed to fetch 。我什至没有对代码进行任何更改,这是所有 React 组件的问题。

我得到一个有效的回应:

在此处输入图像描述

但同时也收到此错误:

在此处输入图像描述

 fetch(url)
.then(res => res.json())
.then(data => {
  // do something with data
})
.catch(rejected => {
    console.log(rejected);
});

当我删除凭据时:“include”,它适用于本地主机,但不适用于服务器。

我尝试了 StackOverflow 和 GitHub 上提供的所有解决方案,但对我来说都行不通。

原文由 Amanshu Kataria 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 6k
2 个回答

这可能与您从后端收到的响应有关。如果它在服务器上工作正常,那么问题可能出在响应标头中。

检查响应标头中 Access-Control-Allow-Origin 的值。通常 fetch API 会抛出 fail to fetch 即使在收到响应后,当响应头 Access-Control-Allow-Origin 并且请求的来源不匹配时。

原文由 yugantar 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

用给定的对象对象填充 Headers 对象头:

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

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

方法步骤有时会抛出 TypeError:

delete(name) 方法的步骤是:

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

get(name) 方法的步骤是:

  1. 如果 name 不是名称,则抛出 TypeError。
  2. 返回从这个头列表中获取名称的结果。

has(name) 方法的步骤是:

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

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

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

要从对象中提取主体和 Content-Type 值,以及可选的布尔保持活动(默认为 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 为空字符串,则将请求的referrer 设置为“no-referrer”。

3. 否则:

1. 让parsedReferrer 为用baseURL 解析referrer 的结果。

2. 如果parsedReferrer 失败,则抛出TypeError。

18. 如果模式是“navigate”,则抛出一个TypeError。

23. 如果请求的缓存模式是“only-if-cached”并且请求的模式不是“同源”则抛出一个TypeError。

27. 如果 init[“method”] 存在,则:

2.如果method不是一个方法或者method是一个禁止的方法,那么抛出一个TypeError。

32. 如果这个请求的模式是“no-cors”,那么:

1. 如果此请求的方法不是 CORS 安全列表方法,则抛出 TypeError。

35. 如果 init[“body”] 存在且非空或 inputBody 非空,并且请求的方法是 GETHEAD ,则抛出 TypeError。

38. 如果 body 不为空且 body 的源为空,则:

1. 如果此请求的模式既不是“同源”也不是“cors”,则抛出 TypeError。

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

clone() 方法的步骤是:

  1. 如果这被打扰或锁定,则抛出 TypeError。

在响应类中:

新的 Response(body, init) 构造函数步骤是:

2. 如果 init[“statusText”] 与原因短语令牌生产不匹配,则抛出 TypeError。

8. 如果 body 不为空,则:

1. 如果 init[“status”] 是空主体状态,则抛出 TypeError。

static 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 中设置的每个选项的限制来找到有关它们的信息。

原文由 Gregory Ledray 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题