HttpRequestBase 类
1 构造函数
constructor(baseUrl) {
const basePort = getUrlPort(baseUrl);
this.baseUrl = baseUrl;
this.baseUrlWithPort2 = baseUrl.replace(/(\/\/.*:)(\d+)/, `$1${basePort + 1}`);
this.basePort = basePort; // 原始端口
this.queue = {};
this.triggerTime = '';
this.alikeUrl = []; // ajax标识--请求地址&请求方式
this.CancelToken = axios.CancelToken;
// 在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
this.removeAlikeUrl = config => {
// 截取 baseUrl 后的字符串
let configUrl =
config.url.indexOf(config.baseURL) !== -1
? config.url.substring(config.baseURL.length, config.url.length)
: config.url;
for (var i = this.alikeUrl.length - 1; i >= 0; i--) {
if (this.alikeUrl[i].u === configUrl + '&' + config.method) {
this.alikeUrl[i].cancel('axios请求被取消');
this.alikeUrl.splice(i, 1);
break;
}
}
};
}
2 事件处理程序
2.1 请求封装
request(options) {
// 创建 axios 请求
const instance = axios.create();
// 请求参数处理
options = this.getInsideConfig(options);
// 请求响应拦截
this.interceptors(instance, options.url);
return instance(options);
}
2.2 请求参数处理
transformRequest
允许在向服务器发送前修改请求数据,只能用put post patch请求方法
getFinalBaseURL(apiUrl) {
return checkIsUsePort2(apiUrl, this.basePort) ? this.baseUrlWithPort2 : this.baseUrl;
}
getInsideConfig(options) {
const config = {
baseURL: this.getFinalBaseURL(options.url),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: SessionIdConfigure.getLocalId()
},
// 在向服务器发送前修改请求数据
transformRequest: [
data => {
let ret = '';
for (var i in data) {
if (data[i] instanceof Array) {
for (var j in data[i]) {
ret += i + '=' + (
typeof data[i][j] === 'object'
? JSON.stringify(data[i][j])
: encodeURIComponent(data[i][j])
) + '&';
}
} else {
if (
!(String(data[i]) === 'null' || String(data[i]) === 'undefined') &&
String(data[i]).indexOf('NaN-aN-aN') === -1
) {
ret += i + '=' + encodeURIComponent(data[i]) + '&';
} else {
ret += i + '=&';
}
}
}
return ret;
}
],
...options
}
return config;
}
2.3 取消loading效果
destroy(url) {
if (this.queue[url]) delete this.queue[url];
if (!Object.keys(this.queue).length) {
store.commit('appLoading/display', false);
}
}
2.4 请求响应拦截处理
interceptors(instance, url) {
let isNoSpin = proStorage.fetch('noSpin');
isNoSpin && proStorage.save('noSpin', 'false');
// 请求拦截
// 响应拦截
}
- 请求拦截
/**
* 请求拦截
* @property {Function} config.cancelTrigger 可传入自定义请求取消方法
*/
instance.interceptors.request.use(
config => {
this.removeAlikeUrl(config); //在一个ajax发送前执行一下取消操作
let cancelTrigger = config.cancelTrigger;
if (!config.cancelTrigger) {
config.cancelToken = new this.CancelToken(c => {
cancelTrigger = c;
});
}
// ajax标识--请求地址&请求方式
this.alikeUrl.push({ u: config.url + '&' + config.method, cancel: cancelTrigger });
// 触发时间
this.triggerTime = new Date();
// 添加全局的loading...
if (!Object.keys(this.queue).length && (!isNoSpin || isNoSpin === 'false')) {
store.commit('appLoading/display', true);
}
if (!isNoSpin || isNoSpin === 'false') {
this.queue[url] = true;
}
isNoSpin = null;
return config;
},
error => {
return Promise.reject(error);
}
);
- 响应拦截
instance.interceptors.response.use(
res => {
// 在一个ajax响应后再执行一下取消操作
this.removeAlikeUrl(res.config);
this.destroy(url);
const { data, status } = res;
const {
config: { method }
} = JSON.parse(JSON.stringify(res));
if (
store.state.interfaceLog.storageLog.developmentOff &&
url.indexOf('analysis/api/') !== -1 &&
method === 'post' &&
data.code === 1
) {
let query_key, query_name, query_time, exec_time;
if (data.data && Object.keys(data.data).length > 0) {
query_key = data.data['query_key'];
query_name = data.data['query_name'];
query_time = data.data['query_time'];
exec_time = data.data['exec_time'];
} else if (data.os_data && data.os_data[0] && Object.keys(data.os_data[0]).length > 0) {
query_key = data.os_data[0].data['query_key'];
query_name = data.os_data[0].data['query_name'];
query_time = data.os_data[0].data['query_time'];
exec_time = data.os_data[0].data['exec_time'];
}
const logData = {
url,
query_key,
query_name,
query_time,
exec_time,
title: router.currentRoute.meta.title,
param: res.config.data,
triggerTime: this.triggerTime,
msg: data.msg
};
store.commit('addStorageLog', logData);
}
interceptResponse(data.code);
return { data, status };
},
error => {
this.destroy(url);
console.error('response: ', typeof error === 'object' ? error.message : error);
if (!axios.isCancel(error)) {
this.removeAlikeUrl(error.config);
let errorInfo = error.response;
if (!errorInfo) {
const {
request: { statusText, status },
config
} = error;
errorInfo = {
statusText,
status,
request: { responseURL: config.url }
};
}
interceptResponse(errorInfo.status);
}
return Promise.reject(error);
}
);
2.5 类外方法
- 请求过期提示
function interceptResponse(status) {
if (status === 401 && router.currentRoute.name !== 'Login') {
Modal.warning({
title: '提示',
content: 'Session已过期!请您确认返回登录页面重新登录!',
onOk: () => {
store.commit('user/logout');
}
})
}
}
- 是否使用第二端口
// 以 /analysis 和 /query 开头的接口需切换端口,现在的匹配模式包含了前后的'/'符号
function checkIsUsePort2(url, basePort) {
return (basePort === 9001 || basePort >= 30000) && /^\/(analysis|query)[^/]*\//.test(url);
}
- 获取地址端口号
function getUrlPort(url) {
let result = url.match(/\/\/.*:(\d+)/);
return result && Number(result[1]);
}
标签:axios,封装,&&,url,data,版本,error,query,config
From: https://www.cnblogs.com/pleaseAnswer/p/17104756.html