背景

提及前端与服务器端的异步通信,离不开 Ajax (Asynchronous JavaScript and XML)。实际上我们常说的 Ajax 并非指某一项具体的技术,它主要是基于用脚本操作 HTTP 请求的 Web 应用架构。最早出现在 Jesse James Carrett 于 2005年2月发表一篇《Ajax:A New Approach to Web Applications》中提出的一个新概念。

在 Ajax 中涉及到的 JavaScript 方面的技术,即 XMLHttpRequest(以下简称 XHR)。很长一段时间我们都是通过 XHR 来与服务器建立异步通信。然而在使用的过程中,我们发现 XHR 是基于事件的异步模型,在设计上将输入、输出和事件监听混杂在一个对象里,且必须通过实例化方式来发请求。配置和调用方式混乱,不符合关注分点离原则。

关注点分离原则所描述的是系统的元素应该表现出互不相干的目的。也就是说,没有会分担另外一个元素职责的,或者其它不相干职责的元素。

正是由于 XHR 在使用上的不便,许多前端库就将进行封装,方便开发者调用。其中影响和使用范围最广的当属 jQuery 提供的 $.ajax 方法。该方法最为先进之处在于,从 jQuery 1.5 开始,$.ajax()返回的jqXHR对象 实现了 Promise 接口, 使它拥有了 Promise 的所有属性,方法和行为。

直到 Fetch API 的提出,前端和服务器端的异步通信方面更进了一步。

技术介绍

Fetch API 是近年来被提及将要取代 XHR 的技术新标准,是一个 HTML5 的 API。

Fetch 并不是 XHR 的升级版本,而是从一个全新的角度来思考的一种设计。Fetch 是基于 Promise 语法结构,而且它的设计足够低阶,这表示它可以在实际需求中进行更多的弹性设计。对于 XHR 所提供的能力来说,Fetch 已经足够取代 XHR ,并且提供了更多拓展的可能性。

快速了解

Fetch API 规范明确了用户代理获取资源的语义。原生支持 Promise1,调用方便,符合语义化。可配合使用 ES2016 中的 asyncawait 语法,更加优雅。

通过一个例子来快速了解和使用 Fetch API 最基本的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 获取 some.json 资源
fetch('some.json')
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log('data', data);
})
.catch(function(error) {
console.log('Fetch Error: ', error);
}); // 采用ES2016的 async/await 语法
async function() {
try {
const response = await fetch('some.json');
const data = response.json();
console.log('data', data);
} catch (error) {
console.log('Fetch Error: ', error)
}
}

通过例子我们可以发现,使用 Fetch API 能够快速便捷地进行资源地获取。

可以简单理解为,Fetch API 是面向未来的异步通信 API。

具体用法

fetch 方法

fetch 方法有两种调用方式。

1
2
Promise fetch(String url, [, Object options])
Promise fetch(Request req, [, Object options])
  1. 第一个参数是一个 Request 对象,第二个参数是配置信息,可选
  2. 第一个参数是一个 url,第二个参数是配置信息,可选

可选配置信息是一个 Object 对象,可以包含以下字段:

  • method: 请求的方法,例如:GETPOST
  • headers: 请求头部信息,可以是一个简单的对象,也可以是 Headers 类实例化的一个对象。
  • body: 需要发送的信息内容,可以是 BlobBufferSourceFormDataURLSearchParams 或者 USVString。注意,GETHEAD方法不能包含body。
  • mode: 请求模式,分别有 corsno-corssame-originnavigate 这几个可选值。
    • cors: 允许跨域,要求响应中 Acess-Control-Allow-Origin 这样的头部表示允许跨域。
    • no-cors: 只允许使用 HEADGETPOST方法。
    • same-origin: 只允许同源请求,否则直接报错。
    • navigate: 支持页面导航。
  • credentials: 表示是否发送cookie,有三个选项
    • omit: 不发送cookie
    • same-origin: 仅在同源时发送cookie
    • include: 发送cookie
  • cache: 表示处理缓存的策略。
  • redirect: 表示发生重定向时,有三个选项
    • follow: 跟随。
    • error: 发生错误。
    • manual: 需要用户手动跟随。
  • integrity: 包含一个用于验证资资源完整性的字符串。

Headers

Headers 可用来表示 HTTP 的头部信息,使用 Headers 的接口,你可以通过 Headers() 构造函数来创建一个你自己的 headers对象。

1
2
3
4
5
6
7
8
var headers = new Headers({
"Content-Type": "text/plain",
"Content-Length": content.length.toString(),
"X-Custom-Header": "ProcessThisImmediately",
});
headers.append("X-Custom-Header", "AnotherValue");
headers.has("Content-Type") // true
headers.getAll("X-Custom-Header"); // ["ProcessThisImmediately", "AnotherValue"]

Headers 提供 appenddeletegetgetAllhassetforEach等这些实例方法,可供开发者更加灵活地配置请求中的 headers。

Request

Request 类用于描述请求内容。构造函数接受的参数与fetch方法一致,这里就不展开介绍了。我们可以这么理解,事实上fetch方法在调用时,会将传入的参数构造出一个 Request 对象并执行。

1
2
3
4
5
6
7
var URL = '//api.some.com';
var getReq = new Request(URL, {method: 'GET', cache: 'reload'});
fetch(getReq).then(function(response) {
return response.json();
}).catch(function(error) {
console.log('Fetch Error: ', error);
});

Request 接口中的配置项 headers 可以是实例化的 Headers 。

1
2
3
4
5
6
7
8
9
10
11
12
13
var URL = '//api.some.com';
// 实例化 Headers
var headers = new Headers({
"Content-Type": "text/plain",
"Content-Length": content.length.toString(),
"X-Custom-Header": "ProcessThisImmediately",
});
var getReq = new Request(URL, {method: 'GET', headers: headers });
fetch(getReq).then(function(response) {
return response.json();
}).catch(function(error) {
console.log('Fetch Error: ', error);
});

更便捷的是,Request 对象可以从已有的 Request 对象中继承,并拓展新的配置。

1
2
3
4
var URL = '//api.some.com';
var getReq = new Request(URL, {method: 'GET', headers: headers });
// 基于已存在的 Request 实例,拓展创建新的 Request 实例
var postReq = new Request(getReq, {method: 'POST'});

Response

Response 实例是在fentch()处理完promises之后返回的。它的实例也可用通过JavaScript来创建,但只有在ServiceWorkers中才真正有用。

1
var res = new Response(body, init);

其中 body 可以是 BolbBufferSourceFormDataURLSearchParamsUSVString 这些类型的值。

init 是一个对象,可以包括以下这些字段

  • status: 响应状态码
  • statusText: 状态信息
  • headers: 头部信息,可以是对象或者Headers实例

Response 实例提供了以下实例属性,均是只读属性。

  • bodyUsed: 用于表示响应内容是否被使用过
  • headers: 头部信息
  • ok: 表明请求是否成功,响应状态为 200 ~ 299 时,值为 true
  • status: 状态码
  • statusText: 状态信息
  • type: 响应类型
    • basic: 同源
    • cors: 跨域
    • error: 出错
    • opaque: Request mode 设置为 “no-cors”的响应
  • url: 响应地址

Response 实例提供以下实例方法。

  • clone: 复制一个响应对象。
  • arrayBuffer: 将响应数据转换为 arrayBuffer 后 reslove 。
  • bolb: 把响应数据转换为 Bolb 后 reslove 。
  • formData: 把响应数据转换为 formData 后 reslove 。
  • json: 把响应内容解析为对象后 reslove 。
  • text: 把响应数据当做字符串后 reslove 。

浏览器支持

Chrome 45+, Opera 44+,Firefox 51+ 和 IE Edge 等这些版本的浏览器开始支持 Fetch API。移动端浏览器也在逐步得到支持。

我们可以通过对 window.fetch 的能力检测,判断出浏览器是否支持 Fetch API。github 官方推出了一个 Fetch API 的 polyfill 库,可以让更多浏览器提前感受到 Fetch API 的便捷的开发体验。

结语

虽然 Fecth API 使用方便符合语义化,但是现阶段它也有所限制。Fetch API 是基于 Promise,由于 Promise 没有处理 timeout 的机制,所以无法通过原生方式处理请求超时后的中断,和读取进度的能力。但是相信未来为了支持流,Fetch API 最终将会提供可以中断执行读取资源的能力,并且提供可以读取进度的 API。

参考文档

.

了解 Fetch API与Fetch+Async/await的更多相关文章

  1. 已配置好的vue全家桶项目router,vuex,api,axios,vue-ls,async/await,less下载即使用

    github 地址: https://github.com/liangfengbo/vue-cli-project 点击进入 vue-cli-project 已构建配置好的vuejs全家桶项目,统一管 ...

  2. Ajax新玩法fetch API

    目前 Web 异步应用都是基于 XMLHttpRequest/ActiveXObject (IE)实现的, 这些对象不是专门为资源获取而设计的,因而它们的 API 非常复杂,同时还需要开发者处理兼容性 ...

  3. ES6 Fetch API HTTP请求实用指南

    本次将介绍如何使用Fetch API(ES6 +)对REST API的 HTTP请求,还有一些示例提供给大家便于大家理解. 注意:所有示例均在带有箭头功能的 ES6中给出. 当前的Web /移动应用程 ...

  4. Fetch API与POST请求那些事

    简述 相信不少前端开发童鞋与后端联调接口时,都会碰到前端明明已经传了参数,后端童鞋却说没有收到,尤其是post请求,遇到的非常多.本文以node.js作为服务端语言,借用express框架,简要分析客 ...

  5. Fetch API & Async Await

    Fetch API & Async Await const fetchJSON = (url = ``) => { return fetch(url, { method: "G ...

  6. fetch + async await 使用原生JS发送网络请求

    由于现在主流浏览器支持Fetch API,无需引用其他库就能实现AJAX,一行代码就搞定,可以说是非常方便了. export default { name: 'HelloWorld', data() ...

  7. Fetch API 接口参考

    前言 Fetch API是新的ajax解决方案,用于解决古老的XHR对象不能实现的问题,Fetch API 提供了一个获取资源的接口(包括跨域请求),任何使用过 XMLHttpRequest 的人都能 ...

  8. Fetch API 了解 及对比ajax、axois

    Fetch是什么 Fetch 是一个现代的概念, 等同于 XMLHttpRequest.它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性.Fetch被很多浏览器所支 ...

  9. Fetch API & cancel duplicate API & cache API

    Fetch API & cancel duplicate API & cache API const usersCache = new Map<string, User>( ...

随机推荐

  1. ALSA driver--Asoc

    https://blog.csdn.net/zyuanyun/article/details/59170418 ALSA Asoc框架如下图: Asoc分为machine,platform,codec ...

  2. 每天进步一点点------SOPC的Avalon-MM IP核(二) AVALON总线的IP核定制

    简介 NIOS II是一个建立在FPGA上的嵌入式软核处理器,除了可以根据需要任意添加已经提供的外设外,用户还可以通过定制用户逻辑外设和定制用户指令来实现各种应用要求.这节我们就来研究如何定制基于Av ...

  3. 推荐算法之---FM算法;

    一,FM算法: 1,逻辑回归上面进行了交叉特征.算法复杂度优化从O(n^3)->O(k*n^2)->O(k*n). 2,本质:每个特征都有一个k维的向量,代表的是每个特征都有k个不可告人的 ...

  4. Bugku-CTF加密篇之+[]- (+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.< ++++[ ->.........)

    +[]- +++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.< ...

  5. SDNU_ACM_ICPC_2020_Winter_Practice_2nd

    A - [The__Flash]的矩阵 给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大. Input输入数据的第一行为一个正整数T,表示有T组测试数据.每一组测试数据 ...

  6. 【MySQL】库的操作

    "SQL语言主要用于存取数据.查询数据.更新数据和管理关系数据库系统,SQL语言由IBM开发. SQL语言分为3种类型: DDL语句 数据库定义语言:数据库.表.视图.索引.存储过程,例如C ...

  7. python二维数组的创建

    话不多说,代码伺候 m = [[]*]*3 #创建一个3行5列的二维数组 m[][]= print(m) 输出结果为: 分析: m = [[0]*5]*3只是指向三个空列表的引用. 创建一个二维数组的 ...

  8. .NET中的字符串(5):字符串驻留

    StringBuilder对象 通过上面的分析可以看出,String类型在做字符串的连接操作时,效率是相当低的,并且由于每做一个连接操作,都会在内存中创建一个新的对象,占用了大量的内存空间.这样就引出 ...

  9. js的JSON新方法和历史记录管理

    今天看妙味的视频,一下是一些简单的笔记: 1.JSON的一些新方法: JSON.stringify(); JSON.parse(); 第一个是把js脚本转换成JSON的字符串形式. 而第二个则是吧这种 ...

  10. 【代码学习】PYTHON中的静态方法和类方法

    一.类方法 是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大 ...