这是我参与8月更文挑战的第26天,活动详情查看: 8月更文挑战
序言
在以往的开发中 JavaScript 的网络请求,有一个术语 “AJAX”(Asynchronous JavaScript And XML 的简称)。我们不必使用 XML:这个术语诞生于很久以前,所以这个词一直在那儿。直到后来,一种现代通用的通信方法出现了,那就是fetch,旧版本的浏览器都不支持,但是现代浏览器中大多都支持。今天我们就来详细的了解一下fetch。
Fetch的基本应用
let promise = fetch(url, [options])
- url —— 要访问的 URL。
- options —— 可选参数:method,header 等。
没有 options,那就是一个简单的 GET 请求,下载 url 的内容。 浏览器立即启动请求,并返回一个该调用代码应该用来获取结果的 promise。
获取响应的两个阶段。
第一阶段:
- 当服务器发送了响应头(response header),fetch 返回的 promise 就使用内建的 Response class 对象来对响应头进行解析。在这个阶段,我们可以通过检查响应头,来检查 HTTP 状态以确定请求是否成功
- 如果 fetch 无法建立一个 HTTP 请求,例如网络问题,亦或是请求的网址不存在,那么 promise 就会 reject。异常的 HTTP 状态,例如 404 或 500,不会导致出现 error。
- 我们可以在 response 的属性中看到 HTTP 状态
3.1 status —— HTTP 状态码,例如 200。 3.2ok —— 布尔值,如果 HTTP 状态码为 200-299,则为 true。 例1
let response = await fetch(url);
if (response.ok) { // 如果 HTTP 状态码为 200-299
// 获取 response body(此方法会在下面解释)
let json = await response.json();
} else {
alert("HTTP-Error: " + response.status);
}
第二阶段:
- 为了获取 response body,我们需要使用一个其他的方法调用。Response 提供了多种基于 promise 的方法,来以不同的格式访问 body。
- response.text() —— 读取 response,并以文本形式返回 response,
- response.json() —— 将 response 解析为 JSON,
- response.formData() —— 以 FormData 对象)的形式返回 response,
- response.blob() —— 以 [Blob]具有类型的二进制数据)形式返回 response,
- response.arrayBuffer() —— 以 [ArrayBuffer](低级别的二进制数据)形式返回 response
例子2:从Github获取最新的数据
let url = 'https://api.github.com';
let response = await fetch(url);
let commits = await response.json();
alert(commits[0].author.login);
也可以使用纯 promise 语法,不使用 await
fetch('https://api.github.com')
.then(response => response.json())
.then(commits => alert(commits[0].author.login));
要获取响应文本,需要使用 await response.text() 代替 .json()
let response = await fetch('https://api.github.com');
let text = await response.text(); // 将 response body 读取为文本
alert(text.slice(0, 20) + '...');
以下是一个读取为二进制格式的示例,我们 fetch 并显示一张fetch规范中的图片
let response = await fetch('/article/fetch/coolFish.svg');
let blob = await response.blob(); // 下载为 Blob 对象
// 为其创建一个 <img>
let img = document.createElement('img');
img.style = 'position:fixed;top:10px;left:10px;width:100px';
document.body.append(img);
// 显示它
img.src = URL.createObjectURL(blob);
setTimeout(() => { // 3 秒后将其隐藏
img.remove();
URL.revokeObjectURL(img.src);
}, 3000);