2024-11-29 16:04:56 +08:00

285 lines
8.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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),
}