vlambda博客
学习文章列表

fetch 如何在 Javascript 中工作

如果我们想从 API 获取数据,或者将数据发布到服务器,我们必须使用 fetch API。正如名称所暗示的那样,fetch()为我们提供了一种通过请求和响应发送和接收 HTTP 请求的方法。

fetch()函数是一个全局函数,最常用于与 API 交互。如果您不熟悉它,那么让我们来看看fetch()它是如何工作的。

如何在 Javascript 中使用 fetch

fetch 最基本的用法需要一个参数——我们要获取的 URL。当我们运行 fetch 时,它会返回一个响应:

let fetchExample = fetch("https://fjolt.com").then((res) => {
   // Do something with res
});

很酷的是 res 有一堆内置函数:

  • res.text()- 返回 URL 的文本内容。如果是网站,则返回 HTML。

  • res.json()- 返回格式化的 JSON 数据(如果存在)。

  • res.blob()- 返回 blob 数据(如果存在)。

  • res.arrayBuffer()- 如果存在,则返回 arrayBuffer 数据。

  • res.formData()- 返回 formData 数据,如果有的话。让我们看两个例子,来展示它是如何工作的。

使用 Javascript Fetch 获取网站的 HTML 内容

由于res.text()给了我们一个 URL 的文本内容,我们可以使用它来获取一个站点的整个 HTML 内容。一旦我们运行res.text(),我们可以用另一个 then 捕获响应,并在控制台记录它:

let websiteData = fetch("https://fjolt.com").then(res => res.text()).then((data) => {
   return data;
});
// Now contains our website's HTML.

如果链接不存在,或者发生错误,我们的响应对象将返回错误。例如,找不到页面将返回 404,或者网关错误将返回 502。

使用 Javascript Fetch 从链接中获取 JSON 内容

fetch 的另一个常见用途是获取数组的响应。如果我们想从 JSON 格式的 API 中获取响应,我们可以使用 res.json()。例如,以下代码将从 URL 返回一个 JSON 对象,假设 URL 正在发送有效的 JSON:

let apiResponse = fetch("https://fjolt.com/api").then(res => res.json()).then((data) => {
  return data;
});
// Now contains a JSON object - assuming one exists

Javascript Fetch 的选项

由于 fetch 发送和接收 HTTP 请求,它有很多我们可以使用的选项,以及 URL。它们作为一个对象出现在 URL 之后 - 即 fetch(URL, { options })。如果您以前使用过 HTTP 请求,那么您可能会很熟悉。所有可用选项的示例如下所示:

fetch("https://fjolt.com/", {
   body: JSON.stringify({ someData: "value" })
   method: 'POST'
   mode: 'cors'
   cache: 'no-cache'
   credentials: 'same-origin'
   headers: {
     'Content-Type': 'application/json'
  },
   redirect: 'follow'
   referrerPolicy: 'no-referrer'
});

以下是每个含义的摘要:

  • body包含文本的主体。在这个例子中,我们发送了一些 JSON,它需要被字符串化。方法是标准的 HTTP 方法。可以是POST/ GET/ DELETE/ PUT/ CONNECT/ PATCH/ TRACE/ OPTIONS

  • 模式是指是否接受跨源请求。可以是cors// no-corssame-origin

  • 缓存是指浏览器如何与缓存交互。可以是default/ no-cache/ reload/ force-cache/ only-if-cached

  • 凭据是指是否应与请求一起发送跨源 cookie。可以是include// same-originomitheaders 包含与请求关联的任何标头。它可以包含任何 HTTP 标头 - 例如,这里显示Content-Type- 但您也可以拥有自定义 HTTP 标头。redirect 确定如果获取的 URL 重定向会发生什么。可以是follow// errormanual

  • referrerPolicy确定随请求传递多少引荐来源信息。可以是no-referrer/ no-referrer-when-downgrade/ origin/ origin-when-cross-origin/ same-origin/ strict-origin/ strict-origin-when-cross-origin/ unsafe-url

Javascript Fetch 是异步的

当我们使用 fetch 时,它会转到我们定义的 URL,收集信息并将响应返回给我们。这不是立即的,因为加载 URL 并将其返回需要时间。如果我们只是单独运行 fetch,控制台日志将返回一个 Promise,而不是来自我们想要的 URL 的响应:

let apiResponse = fetch("https://fjolt.com/api");

console.log(apiResponse); // Returns Promise<Pending>

发生这种情况是因为 fetch() 函数运行,但 Javascript 不等待响应。因此,如果我们想要访问响应,我们必须明确告诉 Javascript 等待它。

等待 fetch() 有两种方法:

  • 我们可以使用then,并在 then 循环中操作 fetch() 的响应。

  • 我们可以使用await,并在使用其内容之前等待 fetch 返回。

使用 then 等待 Javascript 中的获取

从调用中访问数据的一种方法fetch()是将然后链接到我们的 fetch 上,允许我们从我们的 URL 访问响应。的内容fetch()可以在 then() 回调函数中进行操作,但不能在它之外进行操作。例如:

let apiResponse = fetch("https://fjolt.com/api").then(res => res.json()).then((data) => {
   console.log(data);
   // We can do anything with the data from our api here.
   return data;
});

console.log(apiResponse); 

// This will return Promise<Pending>

// That means we can't use the apiResponse variable
// outside of the then() function.  

如果我们想使用fetch()then 函数之外的内容,我们必须使用await.

在 Javascript 中使用 await 等待获取

等待获取的另一种方法是使用 await 关键字。大多数现代浏览器都支持顶级等待,但如果您担心支持,或者使用 14.8 之前的 Node.JS 版本,您需要将任何等待代码包装在异步函数中。

如果我们使用 await,我们可以在函数或代码中的任何地方使用来自 API 的响应,并使用任何响应函数,例如text()json()在其上。例如:

// Typically we wrap await in an async function
// But most modern browsers and Node.JS support
// await statements outside of async functions now.
async getAPI() {
   let apiResponse = await fetch("https://fjolt.com/api");
   let response = apiResponse.json();
   // Since we waited for our API to respond using await
   // The response variable will return the response from the API
   // And not a promise.
   console.log(response);
}

getAPI();

结论

在本指南中,我们介绍了 fetch 的工作原理。我们已经展示了您可以随fetch()请求一起发送的不同选项,以及如何使用 Javascript 中的异步概念等待响应。fetch()是 Javascript 中一个非常强大的工具,并且一直在大型产品中经常使用。希望您喜欢这篇文章。