不了解fetch的可先去看官方文档
话不多说直接上代码
export default class HTTP {
/**
* 拼接url参数
* @returns {String}
*/
static paramsToUrl(url, data) {
let esc = encodeURIComponent;
let queryParams = Object.keys(data)
.map(k => `${esc(k)}=${esc(data[k])}`)
.join('&');
if (queryParams) url += `?${queryParams}`;
return url;
}
/**
* 设置返回默认请求头
* @returns {Object}
*/
static getHeaders() {
return {
headers: {}
};
}
/**
* 默认超时时间
*/
static timeout = 60 *1000;
static showLoading() {
//根据实际情况写相应的loading图
}
static hideLoading() {
}
/**
* 统一处理后台返回的结果, 包括业务逻辑报错的结果
* @param result
*/
static handleResult(result, cusOperation) {
return result;
}
/**
* 统一处fetch的异常, 不包括业务逻辑报错
* @param result
* ps: 通过 this.isHandleError 来判断是否需要有fetch方法来统一处理错误信息
*/
static handleFailedResult(result, cusOperation) {
return 'errorMsg';
}
/**
* 控制Fetch请求是否超时
* @returns {Promise}
*/
static fetchTimeout(cusOperation) {
const {isShowLoading} = cusOperation;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (!cusOperation.isFetched) {
// 还未收到响应,则开始超时逻辑,并标记fetch需要放弃
cusOperation.isAbort = true;
// console.error('ERR: 请求超时')
if (isShowLoading) {
HTTP.hideLoading()
}
reject({fetchStatus: "timeout"})
}
}, cusOperation.timeout || HTTP.timeout);
});
}
/**
* 发送fetch请求
* @param fetchUrl
* @param fetchParams
* @param cusOperation 使用者传递过来的参数, 用于以后的扩展自定义的行为
* @returns {Promise}
*/
static cusFetch(fetchUrl, fetchParams, cusOperation) {
const {isShowLoading} = cusOperation;
if (isShowLoading) {
HTTP.showLoading();
}
cusOperation.isFetched = false;
cusOperation.isAbort = false;
// 处理自定义的请求头
if (cusOperation.hasOwnProperty("cusHeader")) {
const {cusHeader} = cusOperation;
fetchParams.headers = Object.assign({}, fetchParams.headers, cusHeader)
}
// 2. 对fetch请求再进行一次Promise的封装
const fetchPromise = new Promise((resolve, reject) => {
fetch(fetchUrl, fetchParams).then(
response => {
// 3. 放弃迟到的响应
if (cusOperation.isAbort) {
// 3. 请求超时后,放弃迟到的响应
return
}
if (isShowLoading) {
HTTP.hideLoading();
}
cusOperation.isFetched = true;
response.json().then(jsonBody => {
if (response.ok) {
// 4. 统一处理返回结果
resolve(jsonBody); //可根据后台数据 调用handleResult()做统一处理 而不是直接返回jsonBody
} else {
//可根据后端返回的错误信息格式做统一处理
reject(HTTP.handleFailedResult({
fetchStatus: "error",
netStatus: response.status,
error: 'msg'
}, cusOperation));
}
}).catch(e => {
const errMsg = e.name + " " + e.message;
reject(HTTP.handleFailedResult({
fetchStatus: "error",
error: errMsg,
netStatus: response.status
}, cusOperation));
});
}
).catch(e => {
const errMsg = e.name + " " + e.message;
// console.error('ERR:', fetchUrl, errMsg)
if (cusOperation.isAbort) {
// 请求超时后,放弃迟到的响应
return
}
if (isShowLoading) {
HTTP.hideLoading()
}
cusOperation.isFetched = true;
// cusOperation.isHandleResult && Toast.info("网络开小差了,稍后再试吧", 2);
reject(HTTP.handleFailedResult({fetchStatus: "error", error: errMsg}, cusOperation));
});
});
return Promise.race([fetchPromise, HTTP.fetchTimeout(cusOperation)]);
}
/**
* get 请求
* @param url
* @param params
* @param cusOperation 使用者传递过来的参数, 用于以后的扩展自定义的行为
* {
* isHandleResult: boolen //是否需要处理错误结果 true 需要/false 不需要
* isShowLoading: boolen //是否需要显示loading动画
* customHead: object // 自定义的请求头
* timeout: int //自定义接口超时的时间
* }
* @returns {Promise}
*/
get(url, params = {}, cusOperation = {isHandleResult: true, isShowLoading: true}) {
if (!cusOperation.hasOwnProperty("isHandleResult")) {
cusOperation.isHandleResult = true
}
if (!cusOperation.hasOwnProperty("isShowLoading")) {
cusOperation.isShowLoading = true
}
const method = "GET";
const fetchUrl = HTTP.paramsToUrl(url, params); // 将参数转化到url上
const fetchParams = Object.assign({}, {method}, HTTP.getHeaders());
return HTTP.cusFetch(fetchUrl, fetchParams, cusOperation);
}
/**
* post 请求
* @param url
* @param params
* @param cusOperation 使用者传递过来的参数, 用于以后的扩展用户自定义的行为
* @returns {Promise}
*/
post(url, params = {}, cusOperation = {isHandleResult: true, isShowLoading: true}) {
if (!cusOperation.hasOwnProperty("isHandleResult")) {
cusOperation.isHandleResult = true
}
if (!cusOperation.hasOwnProperty("isShowLoading")) {
cusOperation.isShowLoading = true
}
const method = "POST";
const body = JSON.stringify(params); // 将参数转化成JSON字符串
const fetchParams = Object.assign({}, {method, body}, HTTP.getHeaders());
return HTTP.cusFetch(url, fetchParams, cusOperation);
}
}
使用示例代码:
const http = new HTTP();
http.get('https://xxx.com/get',{data:'test'}).then((res) => {
console.log(res);
});
http.post('https://xxx.com/post',{data:'test'}).then((res) => {
console.log(res);
});
大功告成