你对Fetch了解多少?

446 阅读2分钟

这是我参与8月更文挑战的第26天,活动详情查看:             8月更文挑战

序言

在以往的开发中 JavaScript 的网络请求,有一个术语 “AJAX”(Asynchronous JavaScript And XML 的简称)。我们不必使用 XML:这个术语诞生于很久以前,所以这个词一直在那儿。直到后来,一种现代通用的通信方法出现了,那就是fetch,旧版本的浏览器都不支持,但是现代浏览器中大多都支持。今天我们就来详细的了解一下fetch。

Fetch的基本应用

let promise = fetch(url, [options])
  1. url —— 要访问的 URL。
  2. options —— 可选参数:method,header 等。

没有 options,那就是一个简单的 GET 请求,下载 url 的内容。 浏览器立即启动请求,并返回一个该调用代码应该用来获取结果的 promise。

获取响应的两个阶段。

第一阶段:

  1. 当服务器发送了响应头(response header),fetch 返回的 promise 就使用内建的 Response class 对象来对响应头进行解析。在这个阶段,我们可以通过检查响应头,来检查 HTTP 状态以确定请求是否成功
  2. 如果 fetch 无法建立一个 HTTP 请求,例如网络问题,亦或是请求的网址不存在,那么 promise 就会 reject。异常的 HTTP 状态,例如 404 或 500,不会导致出现 error。
  3. 我们可以在 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);
}

第二阶段:

  1. 为了获取 response body,我们需要使用一个其他的方法调用。Response 提供了多种基于 promise 的方法,来以不同的格式访问 body。
  2. response.text() —— 读取 response,并以文本形式返回 response,
  3. response.json() —— 将 response 解析为 JSON,
  4. response.formData() —— 以 FormData 对象)的形式返回 response,
  5. response.blob() —— 以 [Blob]具有类型的二进制数据)形式返回 response,
  6. 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);