記錄一下使用ts封裝axios,供參考:
type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'
type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'
interface AxiosRequest {
baseURL?: string;
url: string;
data?: any;
params?: any;
method?: Method;
headers?: any;
timeout?: number;
responseType?: ResponseType;
}
interface CustomResponse {
readonly status: boolean;
readonly message: string;
data: any;
origin?: any;
}
import axios, { AxiosRequestConfig } from 'axios';
// 定義接口
interface PendingType {
url?: string;
method?: Method;
params: any;
data: any;
cancel: Function;
}
// 取消重復請求
const pending: Array<PendingType> = [];
const CancelToken = axios.CancelToken;
// axios 實例
const instance = axios.create({
timeout: 10000,
responseType: 'json'
});
// 移除重復請求
const removePending = (config: AxiosRequestConfig) => {
for (const key in pending) {
const item: number = +key;
const list: PendingType = pending[key];
// 當前請求在數(shù)組中存在時執(zhí)行函數(shù)體
if (list.url === config.url && list.method === config.method && JSON.stringify(list.params) === JSON.stringify(config.params) && JSON.stringify(list.data) === JSON.stringify(config.data)) {
// 執(zhí)行取消操作
list.cancel('操作太頻繁,請稍后再試');
// 從數(shù)組中移除記錄
pending.splice(item, 1);
}
}
};
// 添加請求攔截器
instance.interceptors.request.use(
(request:any) => {
// TODO: handle loading
removePending(request);
request.cancelToken = new CancelToken((c) => {
pending.push({ url: request.url, method: request.method, params: request.params, data: request.data, cancel: c });
});
return request;
},
(error: any) => {
return Promise.reject(error);
}
);
// 添加響應攔截器
instance.interceptors.response.use(
(response: any) => {
removePending(response.config);
const errorCode = response?.data?.errorCode;
switch (errorCode) {
case '401':
// 根據(jù)errorCode,對業(yè)務做異常處理(和后端約定)
break;
default:
break;
}
return response;
},
(error: any) => {
const response = error.response;
// 根據(jù)返回的http狀態(tài)碼做不同的處理
switch (response?.status) {
case 401:
// token失效
break;
case 403:
// 沒有權限
break;
case 500:
// 服務端錯誤
break;
case 503:
// 服務端錯誤
break;
default:
break;
}
return Promise.reject(response || {message: error.message});
}
);
class BaseHttp {
// 外部傳入的baseUrl
protected baseURL: string = process.env. NODE_ENV as string;
// 自定義header頭
protected headers: object = {
ContentType: 'application/json;charset=UTF-8'
}
private apiAxios({
baseURL = this.baseURL,
headers = this.headers,
method,
url,
data,
params,
responseType
}: AxiosRequest): Promise<CustomResponse> {
return new Promise((resolve, reject) => {
instance({
baseURL,
headers,
method,
url,
params,
data,
responseType
}).then((res: any) => {
// 200:服務端業(yè)務處理正常結束
if (res.status === 200) {
// TODO ...
// resolve({});
} else {
resolve({
status: false,
message: res.data?.errorMessage || (url + '請求失敗'),
data: null
});
}
}).catch((err: any) => {
const message = err?.data?.errorMessage || err?.message || (url + '請求失敗');
// eslint-disable-next-line
reject({ status: false, message, data: null});
});
});
}
/**
* GET類型的網(wǎng)絡請求
*/
protected getReq({
baseURL,
headers,
url,
data,
params,
responseType
}: AxiosRequest) {
return this.apiAxios({
baseURL,
headers,
method: 'GET',
url,
data,
params,
responseType
});
}
/**
* POST類型的網(wǎng)絡請求
*/
protected postReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
return this.apiAxios({ baseURL, headers, method: 'POST', url, data, params, responseType });
}
/**
* PUT類型的網(wǎng)絡請求
*/
protected putReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
return this.apiAxios({ baseURL, headers, method: 'PUT', url, data, params, responseType });
}
/**
* DELETE類型的網(wǎng)絡請求
*/
protected deleteReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
return this.apiAxios({ baseURL, headers, method: 'DELETE', url, data, params, responseType });
}
}