Fetch 封装
fetch 本身不支持超时和 abort() 方法,下面的封装利用 Promiss.race 模拟超时,触发 Promiss 的 reject 来实现了abort()
function request(url, data, method = "GET", options = {}) {
// key => value 转换成需要的格式
let items = [];
for (let key in data) {
items.push([key, data[key]]);
}
const body = new URLSearchParams(items).toString();
// 组装参数
let params = {
method: method,
};
if (method === "GET") {
// 如果是GET请求,拼接url
url += "?" + body;
} else {
params.body = body;
}
// 携带cookie
if (options.cookie != undefined) {
params.credentials = "include";
}
if (options.headers != undefined && typeof options.headers == "object") {
params.headers = new Headers(options.headers);
} else {
params.headers = new Headers({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
});
}
const fetchPromise = fetch(url, params)
.then((r) => {
//处理http状态
if (r.status >= 200 && r.status < 300) {
return r;
}
const error = new Error(r.statusText);
error.response = r;
throw error;
})
.then((r) => (options.dataType == "text" ? r.text() : r.json()))
.then((r) => r);
// 强制取消
fetchPromise.abort = function (resolve, reject) {
reject(new Error("fetch abort"));
};
if (options.timeout == undefined) {
return fetchPromise;
}
// 模拟超时
const timeoutPromise = new Promise(function (resolve, reject) {
setTimeout(() => {
reject(new Error("fetch timeout"));
}, options.timeout);
});
return Promise.race([fetchPromise, timeoutPromise]);
}
export function get(url, data, options = {}) {
return request(url, data, "GET", options);
}
export function post(url, data, options = {}) {
return request(url, data, "POST", options);
}
调用方法
post("/api/test",{ title: "标题" },{
dataType: "json",
cookie: true,
headers: { Accept: "application/json", "Content-Type": "application/x-www-form-urlencoded" },
});