二次封装axios和二次封装拦截器

258 阅读3分钟

1. 二次封装 axios

定义
axios 进行全局配置和功能扩展,创建一个符合项目需求的 HTTP 客户端实例。

核心目的

  • 统一配置请求基础路径、超时时间、请求头格式等。
  • 集成项目特定的功能(如错误处理、请求重试、日志记录等)。
  • 简化 API 调用方式,提供更友好的接口。

实现方式
创建一个 axios 实例并导出,通常在 utils/request.js 或类似文件中:

// utils/request.js
import axios from 'axios';

const service = axios.create({
  baseURL: 'https://api.example.com', // 基础 API 路径
  timeout: 5000,                       // 请求超时时间
  headers: {
    'Content-Type': 'application/json',
  },
});

// 这里可以添加拦截器(但不是必须的)
service.interceptors.request.use(
  (config) => {
    // 请求前处理(如添加 token)
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 导出封装后的 axios 实例
export default service;

使用示例

import request from '@/utils/request';

// 直接使用封装后的实例发送请求
request.get('/users').then((res) => {
  console.log(res.data);
});

2. 二次封装拦截器

定义
axios 的请求拦截器(request interceptor)和响应拦截器(response interceptor)进行封装,用于统一处理请求前和响应后的逻辑。

核心目的

  • 请求拦截器:在请求发送前添加通用处理(如添加认证 token、请求参数格式化、请求日志记录等)。
  • 响应拦截器:在响应返回后统一处理(如状态码校验、错误提示、数据格式化等)。

实现方式
通常在封装 axios 实例时添加拦截器,或单独创建拦截器模块:

// utils/interceptors.js
import { ElMessage } from 'element-plus'; // 示例:使用 Element UI 的消息提示

// 请求拦截器
export const setupRequestInterceptors = (instance) => {
  instance.interceptors.request.use(
    (config) => {
      // 添加 token
      const token = localStorage.getItem('token');
      if (token) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    },
    (error) => {
      return Promise.reject(error);
    }
  );
};

// 响应拦截器
export const setupResponseInterceptors = (instance) => {
  instance.interceptors.response.use(
    (response) => {
      // 成功响应(状态码 2xx)的统一处理
      const { code, message, data } = response.data;
      if (code !== 200) {
        ElMessage.error(message || '请求失败');
        return Promise.reject(new Error(message || '请求失败'));
      }
      return data; // 直接返回 data 字段,简化后续使用
    },
    (error) => {
      // 错误响应的统一处理
      const status = error.response?.status;
      switch (status) {
        case 401:
          ElMessage.error('未登录,请重新登录');
          // 跳转到登录页
          break;
        case 403:
          ElMessage.error('权限不足');
          break;
        case 500:
          ElMessage.error('服务器内部错误');
          break;
        default:
          ElMessage.error('网络错误,请重试');
      }
      return Promise.reject(error);
    }
  );
};

使用示例

// utils/request.js
import axios from 'axios';
import { setupRequestInterceptors, setupResponseInterceptors } from './interceptors';

const service = axios.create({
  baseURL: 'https://api.example.com',
});

// 应用拦截器
setupRequestInterceptors(service);
setupResponseInterceptors(service);

export default service;

3. 主要区别对比

对比项二次封装 axios二次封装拦截器
核心功能创建一个定制化的 axios 实例,包含全局配置统一处理请求前和响应后的逻辑
关注点基础配置、请求方式简化、项目特定功能集成请求/响应的预处理和后处理
实现位置通常在 axios 实例创建时配置作为独立模块或在 axios 实例中配置
常见应用场景- 设置 baseURL、超时时间
- 集成请求重试逻辑
- 统一错误处理
- 添加认证 token
- 状态码校验
- 响应数据格式化
- 错误提示
是否依赖对方可以独立存在,但通常会包含拦截器配置依赖 axios 实例,需在实例上注册

4. 最佳实践建议

  1. 结合使用
    通常在二次封装 axios 时会同时封装拦截器,二者结合可以实现更完善的 HTTP 客户端。

  2. 拦截器模块化
    将拦截器逻辑单独封装为模块(如 interceptors.js),提高代码可维护性。

  3. 错误处理统一化
    在响应拦截器中统一处理 HTTP 错误和业务错误,避免在每个 API 调用处重复处理。

  4. 灵活配置
    允许通过环境变量或配置文件动态调整 axios 实例的参数(如 baseURL)。