window对象提供了一个fetch方法,用于实现基于promise的http请求。它取代了最早的XMLHttpRequest实现的ajax请求。
1. 基本内容
1. 基本语法
fetch方法返回一个promise对象。
const promise = fetch(url[, options]);
url--发起请求的路径
options--可选设置。可以设置method, headers, body等,method默认是"GET"。
2. options配置对象
1. 如果不设置options, method默认是GET方法。
fetch(url)
// 相当于
fetch(url, {
method: 'GET'
})
其传参通过url传参
fetch(url+ 'a=1&b=2')
2. 当请求方法为POST/PUT/DELETE等方法时,需要传请求体body和对应的headers
const user = {name: "lyra"};
fetch(url, {
method: 'POST',
body: {// 请求体
user: JSON.stringify(user)
},
headers: {// 请求头
Content-Type: "application/json;charset=utf-8"
}
})
其中请求体body可以接受的参数类型有:
- string 如:JSON格式, 其对应的请求头为application/json; charset=utf-8
- FormData对象 对应的Content-Type:form/multipart
- ArrayBuffer/ArrayBufferView/Blob 二进制
- URLSearchParams对象 对应的Content-Type:application/x-www-form-urlencoded
对于特殊的请求头,如application/json,需要手动进行设置。
headers: {// 请求头
Content-Type: "application/json;charset=utf-8"
}
如果需要传递cookie的凭证,但是又存在跨域问题,则应该设置:
fetch(url, {
// ⚠️ 此处的属性不是位于headers内部
credentials: "include" // 相当于xhr.withCredentials = true
})
如果使用JWT的用户信息校验机制,则需要设置请求头
fetch(url, {
headers: {
// jwtToken是用户登录后,服务端返回的结果;一般存在localStorage中
authorization: `Bearer ${jwtToken}`
}
})
2. 响应对象
1. 获取响应对象response
fetch请求的返回结果是promise内置的Response类的实例。该类提供了很多数据处理方法。
获取response对象的方法有两种:
/***考虑响应失败,即promise的reject状态**********
1. 网络连接出现问题
2. 请求网址不存在
****************************/
//1. async..await
try {
const response = await fetch(url, options)
}catch(e) {
//当fetch的结果是reject
}
// 2. then
fetch(url, options).then(response =>{
// response为响应对象; 主要服务器有响应404, 500也属于resoloved状态
}, () => {
// reject状态
})
2. response的属性
- response.ok 布尔值;状态码200-299时为true
- reponse.status http状态码
- response.body 可读流; 可以实时计算数据的下载量
// Step 1:启动 fetch 并赋值给 reader
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100');
const reader = response.body.getReader();
// Step 2:获取总长度(总块数)
const contentLength = +response.headers.get('Content-Length');
// Step 3:读取数据
let receivedLength = 0; // 当前长度
let chunks = []; // 存放接收到的二进制块的数组(包括 body)
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
chunks.push(value);
receivedLength += value.length;
console.log(`Received ${receivedLength} of ${contentLength}`)
}
// Step 4:将块合并成单个 Uint8Array
let chunksAll = new Uint8Array(receivedLength); // (4.1)
let position = 0;
for(let chunk of chunks) {
chunksAll.set(chunk, position); // (4.2)
position += chunk.length;
}
// Step 5:解码成字符串
let result = new TextDecoder("utf-8").decode(chunksAll);
// 我们完成啦!
let commits = JSON.parse(result);
alert(commits[0].author.login);
- response.headers 响应头
response.headers是一个类型Map类型的对象,可以通过get获取内容
response.headers.get('Content-Type');
// 迭代所有的headers
for(let [key, value] of headers) {
// key, value
}
3. response的方法
用于获取对应类型的响应内容;其调用方法后的返回结果也是一个promise对象
⚠️下面解析请求体的方式只能使用一种;同时使用多种,只有第一个起作用。
- response.json() 获取json对象
- response.text() 获取文本
- response.formData() 获取FromData对象
- response.blob()
- response.arraybuffer() 二进制形式
数据处理的形式也有两种:
// 1. async...await
try {
const response = await fetch(url, options);
const data = await response.json();
} catch (e) {
//
}
// 2. then
fetch(url, options).then(response => response.json())
.then(data => {
//data
}).catch(e= > {
//
})
3. 简单封装
封装后实现,GET和POST等方式的请求体传参形式相同。
// GET方法需要将对象转为查询参数
function obj2Str(obj) {
let arr=[];
for(let key in obj) {
if (obj.hasOwnProperty(key)) {
arr.push(`${key}=${obj[key]}`);
}
}
return arr.join('&');
}
// 传递参数
const data = {
a: 1,
b: 2
}
async function requset(url, objData, method='GET', headers) {
/**1,2只需要使用一个**/
const defaultOptions = {
// 1. 如果后台使用session验证用户信息
"credentials": "include",// 相当于xhr.withCredentials = true,
}
const options = {
...defaultOptions,
method,
headers: {
// 2. 如果后台使用JWT验证用户信息
"Authorization": `Bearer ${jwtToken}`,
...headers
}
};
if (method === 'GET') {
// GET方法通过URL传参
url = `${url}?${obj2Str(objData)}`;
} else {
options = {
...options,
headers: {
"Content-Type": "application/json; charset=utf-8",
...options.headers
},
body: JSON.stringify(data),
}
}
// 发起请求
try {
const response = await fetch(url, options);
const data = await response.json();
return data;
} catch(e) {
// 网络问题或者URL不存在
}
}
function get(url, obj, headers) {
return requset(url, obj, 'GET', headers);
}
function post(url, obj, headers) {
return requset(url, obj, 'POST', headers);
}
来源:https://www.cnblogs.com/lyraLee/p/12273941.html