新版 Axios 封装
import axios, {AxiosRequestConfig, Method} from 'axios';
import {message as AntdMessage} from 'antd';
import _, {debounce} from 'lodash';
import {HEADER, HTTP_REQUEST_URL, TOKEN_NAME, CODE_STATUS} from '@/constants/constants';
import {commonSlice} from '@/store/common';
import store from '@/store/index';
import {getTicketFromUrl, reLogin} from './utils';
export interface RequestConfig {
token?: boolean;
message?: boolean;
}
const defaultConfig: RequestConfig = {
token: true,
message: true,
};
const debouncedShowErrorMessage = debounce((message = '网络连接异常') => AntdMessage.error(message), 500);
const {updateGLoading} = commonSlice.actions;
function checkKeyIgnoreUpCase(target: Record<string, string>, key: string) {
let res = false;
if (typeof target !== 'object' || target === null) {
return res;
}
const keys = Object.keys(target);
res = keys.some(k => {
return k.toLocaleLowerCase() === key.toLocaleLowerCase();
});
return res;
}
const instance = axios.create({
baseURL: HTTP_REQUEST_URL,
timeout: 20000,
withCredentials: true,
});
type InterceptorsConfig = AxiosRequestConfig & {requestConfig: RequestConfig};
instance.interceptors.request.use(
config => {
config.url = `${config.url}`;
if ((config as InterceptorsConfig).requestConfig.token) {
config.headers[TOKEN_NAME] = localStorage.getItem('ticket') || getTicketFromUrl('ticket');
}
store.dispatch(updateGLoading(true));
return config;
},
error => {
store.dispatch(updateGLoading(false));
return Promise.reject(error);
}
);
instance.interceptors.response.use(
response => {
const shouldMessage = (response.config as InterceptorsConfig).requestConfig.message;
const {status, message} = response.data;
switch (status) {
case CODE_STATUS.SUCCESS:
store.dispatch(updateGLoading(false));
return response;
case CODE_STATUS.FAILED:
shouldMessage && AntdMessage.error(_.get(response, 'data.message.global', ''));
store.dispatch(updateGLoading(false));
break;
case CODE_STATUS.EXPIRE:
response.data.result = _.get(response, 'data.result', []);
store.dispatch(updateGLoading(false));
shouldMessage && AntdMessage.error('登录凭证失效,请重新登录');
localStorage.removeItem('ticket');
break;
default:
store.dispatch(updateGLoading(false));
shouldMessage && AntdMessage.error(message);
return;
}
return response;
},
error => {
if (error && error.response) {
const status = error.response.status;
status === 403 && reLogin();
AntdMessage.error(error.message);
} else {
debouncedShowErrorMessage();
}
store.dispatch(updateGLoading(false));
return Promise.reject(error);
}
);
function request(config: AxiosRequestConfig, requestConfig = defaultConfig) {
const GET_CONTENT_TYPE = 'application/x-www-form-urlencoded;charset=UTF-8';
const POST_CONTENT_TYPE = 'application/json;charset=utf-8';
const method = String.prototype.toUpperCase.call(config.method) || 'GET';
const headers = Object.assign({}, HEADER, config.headers);
if (!checkKeyIgnoreUpCase(headers, 'content-type')) {
if (method === 'GET' || method === 'DELETE') {
headers['Content-Type'] = GET_CONTENT_TYPE;
}
if (method === 'POST' || method === 'PUT') {
headers['Content-Type'] = POST_CONTENT_TYPE;
}
}
(config as any).requestConfig = Object.assign(defaultConfig, requestConfig);
return instance(config).then(res => res.data);
}
const requestMethod: Method[] = ['options', 'get', 'post', 'put', 'head', 'delete'];
export type AjaxFunc = <T = any, K = any>(
url: string,
data?: T,
requestConfig?: RequestConfig,
options?: AxiosRequestConfig
) => Promise<K>;
export function fetch<T = any, K = any>(
url: string,
method: Method = 'GET',
data?: T,
requestConfig = defaultConfig,
extraConfig?: AxiosRequestConfig
): Promise<K> {
const casedMethod = method.toUpperCase() as Method;
const config = {
url,
method: casedMethod,
} as AxiosRequestConfig;
if (casedMethod === 'GET') {
config.params = data;
} else {
config.data = data;
}
return request({...extraConfig, ...config}, requestConfig);
}
const ajax = {} as {
[k in Method]: AjaxFunc;
};
requestMethod.forEach(method => {
ajax[method] = <T, K>(api: string, data: T, requestConfig = defaultConfig, opt?: AxiosRequestConfig) =>
fetch<T, K>(api, method, data, requestConfig, opt || {});
});
export default ajax;
import ajax from '@/utils/request';
import capi from './api';
export const getDataSource = async () => {
const result = await ajax.get(capi.sourceData);
return result.data;
};
export const getDataList = async (params: any) => {
const result = await ajax.post(capi.dataList, params);
return result.data;
};