JavaScript 中 Fetch 是如何工作的
译者 | 陈豪
审校 | 梁策 孙淑娟
如果我们想从 API中获取数据或将数据发布到服务器,必须要用到Fetch API。fetch()为我们提供了一种通过请求和响应发送和接收 HTTP 请求的方法,fetch() 函数是一个全局函数,最常用于与 API 交互。
如何在 JavaScript 中使用 Fetch
我们在使用Fetch API获取 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(): 返回数组缓冲区数据
- 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数据的时候,还可以带一些选项,即 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,它必须被字符串化。
- method: 标准的 HTTP 方法。它可以是 POST/GET/DELETE/PUT/CONNECT/PATCH/TRACE/OPTIONS。
- mode: 指是否接受跨域请求,它可以是cors/no-cors/same-origin。
- cache: 指浏览器如何与Cache交互。 它可以是 default/no-cache/reload/force-cache/only-if-cached。
- Credentials: 指是否与请求一起发送跨域 Cookie。它可以是include/same-origin/omit。
- Headers: 可以包括与请求关联的任何头部, 例如HTTP 头部这里显示 “Content-Type”,但你也可以拥有自定义 HTTP 头部。
- Redirect: 决定了如果Fetch来的URL重定向会发生什么。它可以是follow/error/manual。
- referrerPolicy: 确定请求传递的referrer信息量。它可以是 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 返回。
在 JavaScript 中使用 Then 等待Fetch
从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.
如果我们想在 then 函数之外使用 fetch() 的内容,则必须使用 await。
在 JavaScript 中使用 Await 等待Fetch
等待Fetch的另一种方法是使用 await 关键字。大多数的浏览器都支持Top-level awaits,如果你使用的是Node.JS 14.8 之前的版本,你需要将await相关的代码打包到异步函数中。
如果我们使用 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 中的一个强大工具,经常在一些优秀项目中发挥重要作用。
译者介绍
陈豪,51CTO社区编辑,具有6年工作经验的高级系统工程师。擅长技能有Linux内嵌汇编语言,Python,C,C++,Java,Linux内核分析,智能机器人软件设计等。
原文标题: How Fetch Works in JavaScript ,作者:Johnny Simpson
- 刷算法题常用的 JS 基础扫盲
- 跨区域、Kubernetes集群运行数据库实践指南
- 13个你应该知道的 Webpack 优化技巧
- Python进行数据可视化,你会用什么库来做呢?
- Python常见报错及解决方案,建议收藏!
- 介绍一款进阶版的 Pandas 数据分析神器:Polars
- Python包管理工具之Pipenv
- 「Spring」Boot Docker 认证指南(上)
- 基于Electron开发Hosts切换工具的“踩坑”之旅
- 2022 年需求中优秀的 DevOps 工具
- 一日一技:如何实现带Timeout的Input?
- 13 个非常有用的 Python 代码片段,建议收藏!
- [科普文] 浅谈 Function Programing 编程范式
- 什么是Pulsar函数流处理应用?
- Flask vs Django: 该如何选择Python框架?
- 十个用图表解释JavaScript 闭包的面试题
- 漫谈 CSS 方法论
- 超详细的日常开发必备神器 HttpUtil
- 理想中的接口自动化项目你了解吗?
- 让我们一起聊聊 Django 框架