Axios 封装
Axios 是一个基于 Promise 的 HTTP 客户端,可以用在浏览器和 node.js 环境中。
Axios 简单封装,提供了请求拦截器、响应拦截器、错误处理等功能。还提供了一个额外的request请求方法,支持泛型、类型友好、错误优先。
实现源码
ts
import axios, {
AxiosError,
type InternalAxiosRequestConfig,
type AxiosRequestConfig,
type AxiosResponse
} from 'axios';
export interface IBaseResponse<T = unknown> {
code: number;
msg: string;
data?: T;
}
interface IConfigHeader {
headers?: {
isToken?: boolean;
};
}
export const instance = axios.create({
baseURL: import.meta.env.VITE_BASE_API,
timeout: 5000,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
});
instance.interceptors.request.use(
(config: InternalAxiosRequestConfig & IConfigHeader) => {
if (config.headers.isToken !== false) {
const token = 'token';
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
}
);
instance.interceptors.response.use(
(res: AxiosResponse<IBaseResponse | Blob>) => {
const data = res.data;
if (data instanceof Blob || data.code === 200) {
return res;
}
// 业务错误
// message.error(data.msg);
return Promise.reject(new AxiosError(data.msg));
},
(error: AxiosError) => {
// 处理取消请求错误
if (error.code === 'ERR_CANCELED') {
return Promise.reject(error);
}
// 超出 2xx 范围的http状态码都会触发该函数。包括网络错误和超时
// message.error(error.response?.statusText || error.message);
return Promise.reject(error);
}
);
const request = <T extends IBaseResponse | Blob, C = any>(
config: AxiosRequestConfig<C> & IConfigHeader
) => {
return new Promise<[error?: AxiosError, data?: T]>((resolve) => {
instance
.request<T>(config)
.then((res) => {
resolve([undefined, res.data]);
})
.catch((error: AxiosError) => {
resolve([error]);
});
});
};
export default request;基本用法
request 方法
对错误处理友好,无需使用try...catch或.catch获取错误信息。
ts
import request, { instance, type IBaseResponse } from '@utils/plugins/request';
const getUserInfo = () => {
return request<IBaseResponse<{ name: string; age: number }>>({
url: '/user/info',
method: 'GET'
});
};
const test1 = async () => {
// 错误优先
const [err, data] = await getUserInfo();
if (err) {
console.error(err); // AxiosError
return;
}
// { code: 200, message: 'success', data: { name: 'test', age: 18 } }
console.log(data);
}
test1();axios 实例
可以调用axios的instance实例的方法,如get、post、request等。
ts
const login = (data: { username: string; password: string }) => {
return instance.request<IBaseResponse<string>>({
url: '/login',
method: 'POST',
data
});
}
const test2 = () => {
login({ username: 'test', password: '123456' }).then((res) => {
console.log(res.data); // { code: 200, message: 'success', data: 'token' }
}).catch((err) => {
console.error(err); // AxiosError
});
}
test2();