之前搞定了Promise,接下来学习Fetch API。封装过AJAX函数的各位肯定能知道XMLHttpRequest的问题(没有封装过的点这里),首先,其所有的功能全部集中在同一对象上,容易书写混乱不易维护的代码;其次,我们都到ES6啦,传统的事件驱动模式,无法适配新的Promise API,因此ES6提供了Fetch API来解决AJAX的问题。
一.Fetch API的特点
1)精细的功能分割:头部信息,请求信息,响应信息等均分布到不同的对象,更利于处理各种复杂的AJAX场景
2)使用Promise API,更利于异步代码的书写
3)Fetch API并非ES6的内容,属于HTML5新增的WEB AP
【注】Fetch并非取代AJAX,而是对AJAX传统的API的改进;这一块内容的学习,需要掌握网络通信的知识,有问题请移步这里
二.Fetch的基本使用
1.参数
该函数有两个参数:一是请求地址(必填),该参数是字符串;二是请求配置(选填),该参数是对象
即:fetch(url, config)
2.请求配置
1)method:请求方法,数据类型是字符串,默认值为GET
2)headers:请求头信息,数据类型是对象【例1】
【例1】点击按钮,发送AJAX请求,可以在Network中看到配置的请求头信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>获取数据</button>
<script>
async function getData() {
const url = "http://101.132.72.36:5100/api/local";
const config = {
method: 'GET',
headers: {
a: 1
}
}
const resp = await fetch(url, config);
}
document.querySelector('button').onclick = function () {
getData();
}
</script>
</body>
</html>
【结果】
3)body:请求体的内容,必须匹配请求头中的Content-Type,请求方法为POST时配置【例2】
【例2】
async function getData() {
const url = "http://101.132.72.36:5100/api/local";
const config = {
method: 'POST',
headers: {
"Content-Type": "application/json",
a: 1
},
body:`{"c":"1"}` //POST格式需要配置
}
const resp = await fetch(url, config);
}
document.querySelector('button').onclick = function () {
getData();
}
【注】以上3点为重点
4)mode:请求模式,数据类型是字符串,有三个属性值
- cors:默认值,配置为该值,会在请求头中加入origin和referer
- no-cors:配置为该值,不会在请求头中加入origin和referer,跨域的时候可能会出现问题
- same-origin:指示请求必须在同一个域中发生,如果请求其他域,则会报错
5)credentials:配置如何携带凭据(cookie),三个属性值
- omit:默认值,不携带cookie
- same-origin:请求同源地址时携带cookie
- include:请求任何地址都携带cookie
6)cache:配置缓存模式
- default:表示fetch请求之前将检查下http的缓存
- no-store:表示fetch请求将完全忽略http缓存的存在,这意味着请求之前将不再检查下http的缓存,拿到响应以后,也不会更新http的缓存
- no-cache:如果存在缓存,那么fetch将发送一个条件查询request和个正常的request,拿到响应后,他会更新http缓存
- reload:表示fetch请求之前将忽略http缓存的存在,但是请求拿到响应后,他将主动更新http缓存
- force-cache:表示fetch请求不顾一切的依赖缓存,即使缓存过期了,它依然从缓存中读取,除非没有任何缓存,那么它将发送一个正常的request
- only-if-cached:表示fetch请求不顾一切的依赖缓存,即使缓存过期了,它依然从缓存中读取,如果没有缓存,它将抛出网络错误(该设置只在mode为same-origin时有效)
3.返回值
fetch函数返回一个Promise对象【图3-1】。当收到服务器的返回结果后,Promise进入resolved状态,状态数据为Response对象【图3-2】;当网络发生错误时(或其他导致无法完成交互的错误)时,Promise进入rejected状态,状态数据为错误信息【图3-3】
【例3】
async function getData() {
const url = "http://101.132.72.36:5100/api/local";
const result = fetch(url);
console.log(`fetch的返回值:`,result);
const resp = await result;
console.log(`状态数据`,resp);
}
document.querySelector('button').onclick = function () {
getData();
}
【结果】
4.Request对象
除了使用基本的fetch方法,还可以通过创建一个Request对象来完成请求(实际上,fetch内部会自动创建一个Request对象)。【注】尽量保证每次请求都是一个新的Request。
【例4】
let req;
//创建一个Request对象
function getRequestInfo() {
if (!req) {
const url = "http://101.132.72.36:5100/api/local";
req = new Request (url, {}); //(地址,配置)
console.log(req);
}
return req.clone(); //得到一个新的request
}
async function getProvinces() {
const resp = await fetch(getRequestInfo());
const result = await resp.json();
console.log(result)
}
getProvinces();
【结果】
5.Response对象
1)ok:Boolean,当响应消息码在200-299之间时为true,其他为false
2)status:number,响应的状态码
3)text():用于处理文本格式的Ajax响应,它从响应中获取文本流,将其读完,然后返回一个被解决为string对象的Promise
4)blob():用语处理二进制文件格式(比如图片或电子表格)的Ajax响应。它读取文件的原始数据,一旦读取完整个文件,就返回一个被解决为blob对象的Promise
5)json():用于处理JSON格式的AJAX的响应。它将JSON数据流转换为一个被解决为Javascript对象的promise
6)redirect():可以用于重定向到另一个URL,它会创建一个新的Promise,已解决来自重定向的URL的响应
【例5】下面给一个例子,发送fetch,然后打印返回数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>获取数据</button>
<script>
async function getData() {
const url = "http://101.132.72.36:5100/api/local";
const result = await fetch(url);
const data = await result.json();
console.log(data);
}
document.querySelector('button').onclick = function () {
getData();
}
</script>
</body>
</html>
【结果】
【注】我们也可以创建Response对象
4.Headers
在Request和Response对象内部,会将传递的请求头对象转换为Headers,Headers对象中的方法:
1)has(key):检查请求头中是否存在指定的key值
2)get(key):得到请求头中对应的key值
3)set(key, value):修改对应的键值对
4)append(key, value):添加对应的键值对
5)keys():得到所有请求头的键的集合
6)values():得到所有的请求头中的值的集合
7)entries():得到所有请求头中的键值对的集合