import axios from 'axios';
import type {
AxiosRequestConfig,
AxiosResponse,
} from 'axios';
import {
setToken,
getToken,
loginOut,
} from '@/core/auth';
import {
updataTokenAPI
} from '@/api/admin/auth'
import {
ElLoading,
} from 'element-plus'
import { ElMessage } from 'element-plus'
axios.defaults.timeout = 100000;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.headers.get['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.baseURL = import.meta.env.VITE_APP_BASE_URL;
const instance = axios.create();
interface YXRequestConfig extends AxiosRequestConfig {
headers?: any
}
export interface RequestConfig {
timeout?: number;//延长时间
then?: boolean;//是否错误了自行处理 不统一报错
hideLoading?: boolean,//是否显示loading
request?: AxiosRequestConfig,//axiox的配置
}
let timer: number;
let loadingInstance1: ReturnType<typeof ElLoading.service> | undefined;
function showLoading() {
clearTimeout(timer);
if (loadingInstance1) return;
loadingInstance1 = ElLoading.service({
fullscreen: true,
lock: true,
text: '加载中...',
background: 'rgba(0,0,0,.6)',
})
}
function hideLoading() {
clearTimeout(timer);
if (loadingInstance1) {
timer = window.setTimeout(() => {
loadingInstance1?.close();
loadingInstance1 = undefined;
}, 200)
}
}
/**
* TODO 客户端请求拦截
*/
instance.interceptors.request.use(function (config) {
let token = getToken();
if (token) {
config.headers['Authorization'] = token;
}
return config;
})
/**
* 服务端返回拦截
*/
instance.interceptors.response.use(function (response: AxiosResponse) {
hideLoading();
if (response.headers.Authorization) {
setToken(response.headers.Authorization)
}
// 对响应数据做点什么
return response;
}, async (error) => {
hideLoading();
if (error.response && error.response.status === 401) {
let username = localStorage.getItem('loginUserName')
//请求刷新token接口
const { data: res } = await updataTokenAPI({
username
})
//保存新的token值
setToken(res);
// 再调用一次未完成的请求啊(用户无感知)
// error.config 就是上一次axios请求的配置对象
// 把新的token赋予到下一次axios请求的请求头中
error.config.headers.Authorization = res
// return到await的地方,将未完成的请求再次发起,
return axios(error.config)
} else if (error.response.status === 500 && error.config.url === '/auth/user/refresh_token') {
// 因为500的情况有很多种,refresh_token失效也是其中一种情况,所有再加上error.config.url === '/v1_0/authorizations'条件,确保是refresh_token失效情况
// 清空所有的token和refresh_toekn,并且强制跳转登录页面
ElMessage.error('身份已过期!');
loginOut();
}
return error
})
let REFRESH_COUNT = 0;
async function toRequest<T = any>(params: AxiosRequestConfig, config: RequestConfig = {}): Promise<ResponseResult<T>> {
if (!config.hideLoading) {
showLoading();
}
let request = config.request || {};
try {
let result = await instance({
...params,
...request,
timeout: config.timeout,
});
let data: ResponseResult<T> = result.data;
// console.log('data--2')
// console.log(data)
if (!(data instanceof Blob)) {
if (data.code === 40002) {
loginOut();
}
//去登录
if (data.code === 10000) {
return Promise.reject();
}
if (data.code !== SUCCESSCODE && !config.then) {
ElMessage.error(data.message);
return Promise.reject(data);
}
}
return data;
} catch (e) {
return Promise.reject(e);
}
}
export function get<T = any>(url: string, data: object = {}, config?: RequestConfig): Promise<ResponseResult<T>> {
return toRequest(
{
url,
method: 'get',
params: data,
},
config,
)
}
export function post<T = any>(url: string, data: object = {}, config?: RequestConfig): Promise<ResponseResult<T>> {
return toRequest<T>(
{
url,
method: 'post',
data: data,
},
config,
)
}
export function downxlsx<T = any>(url: string, data: object = {}, config?: RequestConfig): Promise<ResponseResult<T>> {
return toRequest<T>(
{
url,
method: 'post',
data: data,
},
config,
)
}
export function upload<T = any>(url: string, data: any, config?: RequestConfig): Promise<ResponseResult<T>> {
return toRequest<T>(
{
url,
method: 'post',
data: data,
headers: {
'Content-Type': 'multipart/form-data',
},
},
config,
)
}
export const blobParams = {
request: {
responseType: 'blob',
}
} as const;
token失效问题的解决方案
最新推荐文章于 2024-06-21 15:14:18 发布