fetch
API 允许我们创建一个 HTTP 请求,以便我们在Javascript中完成许多事情——比如从 API 检索数据、将数据发布到服务器,甚至只是获取网页的全部内容。此 HTTP 请求将从提供的 URL 中异步检索数据,并生成某种 HTTP 响应。让我们看看它是如何工作的。
fetch()
函数是一个全局函数,最常用于与 API 交互。如果您不熟悉它,那么您并不孤单 - 所以让我们来看看fetch()
是如何工作的。
fetch 最基本的用法需要一个参数——我们想要获取的 URL。由于fetch
生成 HTTP 请求,我们总是必须提供一个 URL:
let fetchExample = fetch("https://fjolt.com").then((res) => { // Do something with res });
由于 fetch 的结果是异步的,我们可以使用then()
来捕获响应,并对其进行处理。返回的res
或 response 很酷的一点是它有一堆内置方法,可以让我们立即解析从fetch
获得的内容:
res.text()
- 返回 URL 的文本内容。如果是网站,则返回 HTML。res.json()
- 如果存在,则返回格式化的 JSON 数据。res.blob()
- 返回 blob 数据(如果存在)。res.arrayBuffer()
- 返回 arrayBuffer 数据,如果有的话。res.formData()
- 返回 formData 数据,如果有的话。
由于不同的 URL 产生不同类型的内容,上述方法允许我们以任何我们喜欢的方式解析该内容。为了理解这一切是如何工作的,让我们看两个非常常见的例子。
如上所述, res.text()
为我们提供了 URL 的文本内容——因此我们可以使用它来获取 URL 的整个 HTML 内容。一旦我们使用res.text()
捕获我们的响应,我们可以使用另一个then
捕获响应,从而允许我们下载并返回提供的 URL 的内容:
let websiteData = fetch("https://fjolt.com").then(res => res.text()).then((data) => { return data; }); // Now contains our website's HTML.
如果链接不存在或发生错误,我们的response
对象将包含错误。例如,找不到页面将返回404
,或者网关错误将返回502
。
如果 URL 的内容由 JSON 组成,我们可以使用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
了解 fetch 中可用的选项也很重要。它们作为一个对象出现在 URL 之后——即fetch(URL, { options })
。如果您以前使用过 HTTP 请求,那么您可能会很熟悉。下面显示的fetch
函数包含您可以使用的所有可能选项:
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,它需要被字符串化。method
是标准的 HTTP 方法。它可以是POST
/ GET
/ DELETE
/ PUT
/ CONNECT
/ PATCH
/ TRACE
/ OPTIONS
。mode
是指是否接受跨源请求。它可以是cors
/ no-cors
/ same-origin
。cache
是指浏览器如何与缓存交互。它可以是default
/ no-cache
/ reload
/ force-cache
/ only-if-cached
。credentials
是指是否应与请求一起发送跨源 cookie。它可以是include
/ same-origin
/ omit
。headers
包含与请求关联的任何标头。它可以包含任何 HTTP 标头 - 例如,这里显示Content-Type
- 但您也可以拥有自定义 HTTP 标头。redirect
确定如果获取的 URL 重定向会发生什么。它可以是follow
/ error
/ manual
。referrerPolicy
确定随请求传递多少引荐来源信息。它可以是no-referrer
/ no-referrer-when-downgrade
/ origin
/ origin-when-cross-origin
/ same-origin
/ strict-origin
/ strict-origin-when-cross-origin
/ unsafe-url
。当我们使用 fetch 时,它会转到 URL,收集信息,并向我们提供response
。这不是立即的,因为加载 URL、下载并返回需要时间。如果我们只是单独运行 fetch ,那么它之后的控制台日志只会返回一个Promise
,而不是来自我们想要的 URL 的response
:
let apiResponse = fetch("https://fjolt.com/api"); console.log(apiResponse); // Returns Promise<Pending>
发生这种情况是因为fetch()
函数运行,但 Javascript 不等待response
。因此,如果我们想访问response
,我们必须明确告诉 Javascript 等待它。
有两种方法可以等待fetch()
:
then
,并在then()
中操作fetch()
的响应。await
,并在使用其内容之前等待 fetch 返回。使用then
经常用于捕获和处理来自 fetch 的响应。 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.
如果我们想在then
之外使用fetch()
的内容,我们必须使用await
。
等待获取的另一种方法是使用await
关键字。大多数现代浏览器都支持顶级等待,但如果您担心支持,或者使用 14.8 之前的 Node.JS 版本,您需要将任何await
代码包装在async function
中。
如果我们使用 await,我们可以在函数或代码的任何地方使用来自 API 的响应,并在其上使用任何response
函数,例如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();
如果您想了解有关异步操作的更多信息,请在此处阅读我们的异步 Javascript 教程。
在本指南中,我们介绍了 fetch 的工作原理。我们已经展示了您可以通过fetch()
请求发送的不同选项,以及如何使用 Javascript 中的异步概念等待响应。 fetch()
是 Javascript 中一个非常强大的工具,并且一直在大型产品中经常使用。我希望你喜欢这篇文章。