我正在参加「掘金·启航计划」
简介
fetch()
是一种新的 API,大大简化获取资源请求的写法。与 XMLHttpRequest 一样,Fetch 可用于发出同源请求或跨域请求。Fetch 使用的是更简洁、更强大的 API,可将请求与响应分离,并使用 promise 返回响应。
一个基本的 fetch 请求设置起来很简单, 请看下面的代码:
fetch('https://juejin.cn/post/6991413031351615519')
.then((response) => {
return response.json();
})
.then((myJson) => {
console.log(myJson);
});
fetch语法介绍
基础语法:
fetch(url, {options})
url
—— 要访问的 URL。options
—— 可选参数:method,header 等。
options
常用三个属性:
method
:HTTP 请求的方法,POST
、DELETE
、PUT
都在这个属性设置(不设置,默认GET请求)。headers
:一个对象,用来定制 HTTP 请求的表头(有一些无法设置的 header,Content-Length
、Cookie
、Host
等,由浏览器自动生成)。body
:POST 请求的数据体。
其它更多API点 => fetch
fetch
返回的 promise
对象 response
解析:
fetch('https://juejin.cn/post/6991413031351615519')
.then((response) => console.log(response))
fetch
无法建立一个 HTTP 请求,例如网络问题,或是请求的网址不存在等,那么 promise 就会 reject。
我们可以在 response 的属性中看到 HTTP 状态:
status
—— HTTP 状态码,例如 200。ok
—— 布尔值,如果 HTTP 状态码为 200-299,则为true
。
我们可以利用这一点判断请求是否成功:
fetch('https://juejin.cn/post/6991413031351615519')
.then((response) => {
if (response.ok) {
return response.json();
}
return alert(`error:${response.status}`);
})
Response
对象根据服务器返回的不同类型的数据,提供了不同的读取方法
response.text()
:得到文本字符串。response.json()
:得到 JSON 对象。response.blob()
:得到二进制 Blob 对象。response.formData()
:得到 FormData 表单对象。response.arrayBuffer()
:得到二进制 ArrayBuffer 对象。
我们只能选择一种读取 body 的方法。
如果我们已经使用了 response.text()
方法来获取 response,那么如果再用 response.json()
,则不会生效,因为 body 内容已经被处理过了。
封装一个fetch
export const fetch = (url, options) => {
if (!options) options = {};
// 默认same-origin,include不管同源请求,还是跨域请求,一律发送 Cookie。
// if (!options.credentials) options.credentials = 'include';
if (options.body && typeof options.body === 'object') options.body = JSON.stringify(options.body); // 转化JSON 字符串
if (options.body && !options.method) options.method = 'POST'; // 存在body,默认请求方法POST
if (options.method) options.method = options.method.toUpperCase(); // 兼容下,字符串转换为大写
// 提交JSON数据时,如果没传将默认值'text/plain;charset=UTF-8'改为'Content-Type': 'application/json'
if (['POST', 'PUT', 'DELETE'].includes(options.method || '')) {
options.headers = Object.assign(
{},
options.headers || {
'Content-Type': 'application/json',
},
);
}
const checkStatus = res => {
// 根据status做不同的处理
if (res.status === 401) {
window.location.href = '/login';
}
if (res.status === 405 || res.status === 403) {
window.location.href = '/403';
}
if (res.status === 404) {
notification.error({ message: '接口不存在' });
}
return res;
};
const filter = res => {
if (res.code !== 0) {
notification.error({
message: '错误',
description: res.message || '网络错误,请重试!',
});
throw res;
}
res.data = res;
return res.data; // 返回数据
};
return (
window
// 建立连接
.fetch(url, options)
// 检验响应码
.then(res => checkStatus(res))
// 格式转换,这里我就默认json
.then(res => res.json())
// 根据业务需求,进行对应过滤
.then(res => filter(res))
.catch(err => console.log(`请求失败! + url: ${url}`, err))
);
};