axios-instance.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import axios, {type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
  2. // 自定义配置接口
  3. export interface CustomInstanceConfig extends AxiosRequestConfig {
  4. // 可以添加自定义配置
  5. skipAuth?: boolean; // 是否跳过鉴权
  6. }
  7. // 创建 Axios 实例
  8. const axiosInstance: AxiosInstance = axios.create({
  9. baseURL: import.meta.env.VITE_API_BASE_URL || '/api',
  10. timeout: 30000,
  11. headers: {
  12. 'Content-Type': 'application/json',
  13. },
  14. });
  15. // 请求拦截器
  16. axiosInstance.interceptors.request.use(
  17. (config) => {
  18. // 添加 token
  19. const token = localStorage.getItem('token');
  20. if (token) {
  21. config.headers.Authorization = `Bearer ${token}`;
  22. }
  23. return config;
  24. },
  25. (error) => {
  26. return Promise.reject(error);
  27. }
  28. );
  29. // 响应拦截器
  30. axiosInstance.interceptors.response.use(
  31. (response: AxiosResponse) => {
  32. // 根据后端返回格式调整
  33. if (response.data.code !== 0) {
  34. return Promise.reject(new Error(response.data.message || '请求失败'));
  35. }
  36. return response.data;
  37. },
  38. (error) => {
  39. // 统一错误处理
  40. if (error.response?.status === 401) {
  41. // 未授权,跳转登录
  42. window.location.href = '/login';
  43. }
  44. return Promise.reject(error);
  45. }
  46. );
  47. // 自定义实例函数(供 Orval 使用)
  48. export const customAxiosInstance = <T>(config: CustomInstanceConfig): Promise<T> => {
  49. return axiosInstance(config);
  50. };
  51. // 也可以导出第二参数形式(如需处理完整响应)
  52. export const customAxiosInstanceWithFullResponse = <T>(
  53. config: CustomInstanceConfig
  54. ): Promise<AxiosResponse<T>> => {
  55. return axiosInstance(config);
  56. };