用ts封装一个axios
前置知识
axios.create(config) 对axios请求进行二次封装
- 根据指定配置创建一个新的 axios ,也就是每个axios 都有自己的配置
- 新的 axios 只是没有 取消请求 和 批量请求 的方法,其它所有语法都是一致的
const instance = axios.create({
baseURL:"http://localhost:3000"
})
const instance2 = axios.create({
baseURL:"http://localhost:4000"
})
instance({
url:"/posts"
})
instance2({
url:"/posts"
})
axios拦截器
axios.interceptors.request.use(config=>{
console.log("请求拦截器")
return config
},err=>{
return Promise.reject(err)
})
axios.interceptors.response.use(res=>{
console.log("响应拦截器")
return res
},err=>{
return Promise.reject(err)
})
axios取消请求
- 配置 cancelToken 对象
- 缓存用于取消请求的 cancel 函数
- 在后面特定时机调用 cancel 函数取消请求
- 在错误回调中判断如果 error 是cancel ,做相应处理
axios.get("http://localhost:4000",{
cancelToken:new axios.CancelToken(function(c){
cancel = c
})
})
.then(res=>{
console.log("res:",res)
cancel = null
},err=>{
cancel = null
if(err.constructor.name === 'Cancel'){
console.log("取消请求导致error:",err)
}else{
console.log("err:",err)
}
});
实战代码
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;
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];
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)) {
list.cancel('操作太频繁,请稍后再试');
pending.splice(item, 1);
}
}
};
instance.interceptors.request.use(
(request:any) => {
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':
break;
default:
break;
}
return response;
},
(error: any) => {
const response = error.response;
switch (response?.status) {
case 401:
break;
case 403:
break;
case 500:
break;
case 503:
break;
default:
break;
}
return Promise.reject(response || {message: error.message});
}
);
class BaseHttp {
protected baseURL: string = process.env.VUE_APP_BaseURL as string;
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) => {
if (res.status === 200) {
} else {
resolve({
status: false,
message: res.data?.errorMessage || (url + '请求失败'),
data: null
});
}
}).catch((err: any) => {
const message = err?.data?.errorMessage || err?.message || (url + '请求失败');
reject({ status: false, message, data: null});
});
});
}
protected getReq({
baseURL,
headers,
url,
data,
params,
responseType
}: AxiosRequest) {
return this.apiAxios({
baseURL,
headers,
method: 'GET',
url,
data,
params,
responseType
});
}
protected postReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
return this.apiAxios({ baseURL, headers, method: 'POST', url, data, params, responseType });
}
protected putReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
return this.apiAxios({ baseURL, headers, method: 'PUT', url, data, params, responseType });
}
protected deleteReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
return this.apiAxios({ baseURL, headers, method: 'DELETE', url, data, params, responseType });
}
}