285 lines
8.9 KiB
JavaScript
285 lines
8.9 KiB
JavaScript
/**
|
||
* @description: axios封装 - 请求拦截、相应拦截、错误统一处理
|
||
* @param {*}
|
||
* @return {*}
|
||
*/
|
||
import axios from 'axios';
|
||
import { Loading, Message } from 'element-ui';
|
||
import store from "../store";
|
||
import _ from 'lodash';
|
||
import router from "../router";
|
||
import qs from "qs";
|
||
import projectConfig from "./projectConfig";
|
||
|
||
// loading对象
|
||
let loadingInstance;
|
||
|
||
// 请求合并只出现一次loading
|
||
// 当前正在请求的数量
|
||
let loadingRequestCount = 0;
|
||
|
||
// 请求超时时间
|
||
axios.defaults.timeout = 10000;
|
||
|
||
//创建一个axios 实例
|
||
const service = axios.create({
|
||
// baseURL: projectConfig.netHost,
|
||
// baseURL: 'https://lz.dev.trydotec.com:8416/miniapp',
|
||
timeout: 30000,
|
||
});
|
||
|
||
// 请求拦截器
|
||
service.interceptors.request.use(
|
||
config => {
|
||
let loadingTarget = '#app';
|
||
// console.log('request拦截器config参数:', config)
|
||
if(config.loadingTarget){
|
||
loadingTarget = config.loadingTarget
|
||
}
|
||
let target = document.querySelector(loadingTarget);
|
||
if(target && !config.hideLoading){
|
||
// 请求拦截进来调用显示loading效果,默认都有loading效果
|
||
showLoading(loadingTarget);
|
||
}
|
||
let token = sessionStorage.getItem('token')
|
||
// console.log('获取token',token)
|
||
// let token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2M2Q1OTYxZi1mMTYzLTRjMWYtYjJkYy1iMzFiMjQ5YzA3ZTMiLCJpYXQiOjE2NjE5MjgzODEsImlzcyI6ImFkbWluIiwiYXVkIjoiMiIsInBsYXlsb2FkIjp7ImFyZWFDb2RlIjpudWxsLCJ0ZW5hbnRLZXkiOiJ0ZW5hbnQtMDAwMSIsImRlcHRJZCI6IjEiLCJkaWdlc3QiOm51bGwsIm5hbWUiOiIlRTclOTQlOTglRTclQjQlQTAlRTclOEYlOEQiLCJ1c2VySWQiOiIyIiwidXNlcm5hbWUiOiJnYW5zdXpoZW4ifSwiZXhwIjoxNjYyNjEyMzgxfQ.3GeuL01sIJ6JLbJr4rIz8lHJdtjZVDf9y4hMh_p0If8'
|
||
// 身份令牌
|
||
token && (config.headers['Authorization'] = token)
|
||
return config;
|
||
},
|
||
(error) => {
|
||
hideLoading()
|
||
Promise.error(error)
|
||
}
|
||
)
|
||
|
||
// 响应拦截器
|
||
service.interceptors.response.use(
|
||
response => {
|
||
setTimeout(() => {
|
||
hideLoading()
|
||
}, 200);
|
||
console.log('请求返回结果:', response)
|
||
|
||
// 处理Blob格式的数据
|
||
const res = response.data
|
||
if(res instanceof Blob) {
|
||
return new Promise((resolve, reject) => {
|
||
const reader = new FileReader()
|
||
reader.readAsText(res)
|
||
reader.onload = (e) => {
|
||
const { result } = e.target
|
||
if (result.code) {
|
||
// todo 此处,需要统一对错误做处理
|
||
// Message.closeAll()
|
||
// Message({ message: result.message, showClose: true, type: "error" })
|
||
reject(dealResponseError(result))
|
||
} else {
|
||
resolve(response)
|
||
console.log('请求返回结果11111:', response)
|
||
}
|
||
}
|
||
})
|
||
}else if(res.code) {
|
||
return new Promise((resolve, reject) => {
|
||
if(res.code === 9200) {
|
||
resolve(res.data)
|
||
}else{
|
||
// todo 此处,需要统一对错误做处理
|
||
reject(dealResponseError(res));
|
||
}
|
||
})
|
||
|
||
}
|
||
|
||
// return Promise.resolve(response.data);
|
||
},
|
||
error => {
|
||
console.log('请求报错:', error)
|
||
// todo 此处,需要统一对错误做处理
|
||
|
||
if(error.response.status == 401) {
|
||
Message.closeAll()
|
||
setTimeout(() => {
|
||
hideLoading()
|
||
}, 200);
|
||
// 登录过期&token存在,此时有提示
|
||
Message({ message: '请求要求用户的身份认证', type: "error",customClass:'messageZindex'})
|
||
store.state.token = '';
|
||
sessionStorage.removeItem('token');
|
||
sessionStorage.removeItem('userInfo');
|
||
store.state.userinfo = {};
|
||
store.state.routes = [];
|
||
setTimeout(() => {
|
||
router.push('/login')
|
||
}, 300)
|
||
}
|
||
else
|
||
{
|
||
Message.closeAll()
|
||
Message.error(`请求错误: ${error}`)
|
||
setTimeout(() => {
|
||
hideLoading()
|
||
}, 200);
|
||
if(error.response.status) {
|
||
return Promise.reject(error.response);
|
||
}
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
// 显示loading的函数 并且记录请求次数 ++
|
||
const showLoading = (target) => {
|
||
if(loadingRequestCount === 0) {
|
||
loadingInstance = Loading.service({
|
||
lock: true,
|
||
text: '加载中...',
|
||
target: target || 'body'
|
||
});
|
||
}
|
||
loadingRequestCount++;
|
||
}
|
||
|
||
// 隐藏loading的函数,并且记录请求次数
|
||
const hideLoading = () => {
|
||
if(loadingRequestCount <= 0) return;
|
||
loadingRequestCount--;
|
||
if(loadingRequestCount === 0) {
|
||
toHideLoading();
|
||
}
|
||
}
|
||
|
||
// 防抖:将 300ms 间隔内的关闭 loading 便合并为一次. 防止连续请求时, loading闪烁的问题。
|
||
var toHideLoading = _.debounce(() => {
|
||
loadingInstance.close();
|
||
loadingInstance = null;
|
||
}, 300);
|
||
|
||
const dealResponseError = (error) => {
|
||
let code = error.code ||''
|
||
let msg = error.msg || ''
|
||
switch (code) {
|
||
case 9400:
|
||
break;
|
||
case 9401:
|
||
msg = "当前登录已失效,请重新登录!"
|
||
break;
|
||
case 9403:
|
||
msg = "登陆令牌失效!"
|
||
break;
|
||
case 400:
|
||
msg = "客户端请求的语法错误,服务器无法理解!"
|
||
break;
|
||
case 401:
|
||
msg = "请求要求用户的身份认证!"
|
||
break;
|
||
case 403:
|
||
msg = "服务器理解请求客户端的请求,但是拒绝执行此请求!"
|
||
break;
|
||
case 404:
|
||
msg = "找不到资源(网页)!"
|
||
break;
|
||
case 405:
|
||
msg = "客户端请求中的方法被禁止!"
|
||
break;
|
||
case 500:
|
||
case 9500:
|
||
msg = "服务器内部错误,无法完成请求!"
|
||
break;
|
||
case 503:
|
||
msg = "充当网关或代理的服务器,未及时从远端服务器获取请求!"
|
||
break;
|
||
default:
|
||
msg = "网络出错!";
|
||
break;
|
||
}
|
||
console.log('错误处理----code:', code, '----msg----:', msg)
|
||
Message.closeAll()
|
||
// todo 不知道能否预防多个请求都返回登录失效的情况,提示只有1个
|
||
if((code == 9401 || code == 9403) && store.state.token) {
|
||
// 登录过期&token存在,此时有提示
|
||
Message({ message: msg, type: "error",customClass:'messageZindex' })
|
||
store.state.token = '';
|
||
sessionStorage.removeItem('token');
|
||
sessionStorage.removeItem('userInfo');
|
||
store.state.userinfo = {};
|
||
store.state.routes = [];
|
||
setTimeout(() => {
|
||
router.push('/login')
|
||
}, 300)
|
||
}else{
|
||
Message({ message: msg, type: "error",customClass:'messageZindex'})
|
||
}
|
||
|
||
let errorInfo = new Error(msg)
|
||
errorInfo.code = code
|
||
return errorInfo
|
||
}
|
||
// /**
|
||
// * post方法,对应post请求
|
||
// * @param {String} url [请求的url地址]
|
||
// * @param {Object} params [请求时携带的参数]
|
||
// */
|
||
// export function post (url, params) {
|
||
// return new Promise((resolve, reject) => {
|
||
// axios.post(url, QS.stringify(params))
|
||
// .then(res => {
|
||
// resolve(res.data);
|
||
// })
|
||
// .catch(err => {
|
||
// reject(err.data)
|
||
// })
|
||
// });
|
||
// }
|
||
//
|
||
// /**
|
||
// * get方法,对应get请求
|
||
// * @param {String} url [请求的url地址]
|
||
// * @param {Object} params [请求时携带的参数]
|
||
// */
|
||
// export function get (url, param) {
|
||
// return new Promise((resolve, reject) => {
|
||
// axios.get(url, { params: params })
|
||
// .then(response => {
|
||
// resolve(response.data)
|
||
// }, err => {
|
||
// reject(err)
|
||
// })
|
||
// .catch((error) => {
|
||
// reject(error)
|
||
// })
|
||
// })
|
||
// }
|
||
const download = (url, method = "get", param, customConfig) => {
|
||
let obj = {};
|
||
if (method === "get") {
|
||
obj.params = param;
|
||
} else {
|
||
obj.data = param;
|
||
}
|
||
return new Promise((resolve, reject) => {
|
||
service({
|
||
method: method,
|
||
url,
|
||
...obj,
|
||
responseType: "blob",
|
||
})
|
||
.then((res) => {
|
||
resolve(res);
|
||
})
|
||
.catch((error) => {
|
||
reject(error);
|
||
});
|
||
});
|
||
};
|
||
|
||
// export default service
|
||
export default {
|
||
service,
|
||
postFile: (url, param, customConfig) =>download(url, "post", param, customConfig),
|
||
}
|
||
|
||
|
||
|