在前端开发中,axios 是一个非常流行的 HTTP 客户端库,用于发送 HTTP 请求。为了简化代码、统一处理请求和响应、以及增强功能(如请求拦截、响应拦截、错误处理等),通常会对 axios 进行二次封装。
1. 为什么要二次封装 axios?
- 统一配置:可以统一设置请求的基础 URL、超时时间、请求头等。
 - 拦截器:可以在请求发送前和响应返回后添加统一的逻辑(如添加 Token、处理错误等)。
 - 简化调用:封装后可以提供更简洁的 API,减少重复代码。
 - 增强功能 :可以扩展 
axios的功能,例如支持取消请求、缓存请求结果等。 
2. 二次封装的核心功能
2.1 统一配置
通过 axios.create 创建一个实例,并设置全局配置。
2.2 请求拦截器
在请求发送前,对请求进行统一处理(如添加 Token)。
2.3 响应拦截器
在响应返回后,对响应进行统一处理(如错误处理)。
2.4 封装常用方法
封装 GET、POST、PUT、DELETE 等常用方法,简化调用。
3. 代码实现
以下是一个完整的 axios 二次封装示例:
            
            
              javascript
              
              
            
          
          import axios from 'axios';
// 创建 axios 实例
const instance = axios.create({
  baseURL: 'https://api.example.com', // 基础 URL
  timeout: 10000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json', // 默认请求头
  },
});
// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 在发送请求之前做些什么
    const token = localStorage.getItem('token'); // 从本地存储获取 Token
    if (token) {
      config.headers.Authorization = `Bearer ${token}`; // 添加 Token 到请求头
    }
    return config;
  },
  (error) => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);
// 响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 对响应数据做些什么
    if (response.status === 200) {
      return response.data; // 返回响应数据
    } else {
      return Promise.reject(response.data); // 返回错误信息
    }
  },
  (error) => {
    // 对响应错误做些什么
    if (error.response) {
      switch (error.response.status) {
        case 401:
          console.error('未授权,请重新登录');
          break;
        case 404:
          console.error('请求的资源不存在');
          break;
        case 500:
          console.error('服务器内部错误');
          break;
        default:
          console.error('请求失败', error.response.data);
      }
    } else {
      console.error('网络错误,请检查网络连接');
    }
    return Promise.reject(error);
  }
);
// 封装 GET 请求
export const get = (url, params = {}) => {
  return instance.get(url, { params });
};
// 封装 POST 请求
export const post = (url, data = {}) => {
  return instance.post(url, data);
};
// 封装 PUT 请求
export const put = (url, data = {}) => {
  return instance.put(url, data);
};
// 封装 DELETE 请求
export const del = (url, params = {}) => {
  return instance.delete(url, { params });
};
// 导出实例
export default instance;
        4. 功能解析
4.1 统一配置
通过 axios.create 创建了一个实例,并设置了 baseURL、timeout 和默认请求头。这样所有通过该实例发送的请求都会继承这些配置。
4.2 请求拦截器
在请求拦截器中,从本地存储中获取 Token,并将其添加到请求头中。这样可以确保每个请求都携带了认证信息。
4.3 响应拦截器
在响应拦截器中,对响应数据进行统一处理:
- 如果请求成功(状态码为 200),则直接返回响应数据。
 - 如果请求失败(状态码不为 200),则根据状态码进行错误处理,并返回错误信息。
 
4.4 封装常用方法
封装了 GET、POST、PUT、DELETE 等方法,简化了调用方式。例如:
get('/users', { page: 1 })发送一个 GET 请求。post('/users', { name: 'John' })发送一个 POST 请求。
5. 使用示例
5.1 发送 GET 请求
            
            
              javascript
              
              
            
          
          import { get } from './axios';
get('/users', { page: 1 })
  .then((data) => {
    console.log('用户列表:', data);
  })
  .catch((error) => {
    console.error('获取用户列表失败:', error);
  });
        5.2 发送 POST 请求
            
            
              javascript
              
              
            
          
          import { post } from './axios';
post('/users', { name: 'John', age: 30 })
  .then((data) => {
    console.log('用户创建成功:', data);
  })
  .catch((error) => {
    console.error('用户创建失败:', error);
  });
        5.3 发送 PUT 请求
            
            
              javascript
              
              
            
          
          import { put } from './axios';
put('/users/1', { name: 'John Doe' })
  .then((data) => {
    console.log('用户更新成功:', data);
  })
  .catch((error) => {
    console.error('用户更新失败:', error);
  });
        5.4 发送 DELETE 请求
            
            
              javascript
              
              
            
          
          import { del } from './axios';
del('/users/1')
  .then((data) => {
    console.log('用户删除成功:', data);
  })
  .catch((error) => {
    console.error('用户删除失败:', error);
  });
        6. 扩展功能
6.1 取消请求
可以通过 axios.CancelToken 实现请求的取消功能。
            
            
              javascript
              
              
            
          
          import axios from 'axios';
const CancelToken = axios.CancelToken;
let cancel;
get('/users', { page: 1 }, {
  cancelToken: new CancelToken(function executor(c) {
    cancel = c;
  }),
});
// 取消请求
cancel();
        6.2 请求缓存
可以通过在封装中添加缓存逻辑,避免重复请求。
            
            
              javascript
              
              
            
          
          const cache = new Map();
export const getWithCache = (url, params = {}) => {
  const cacheKey = JSON.stringify({ url, params });
  if (cache.has(cacheKey)) {
    return Promise.resolve(cache.get(cacheKey));
  }
  return get(url, params).then((data) => {
    cache.set(cacheKey, data);
    return data;
  });
};
        7. 总结
通过对 axios 的二次封装,可以实现以下目标:
- 统一配置和管理 HTTP 请求。
 - 通过拦截器实现请求和响应的统一处理。
 - 简化常用方法的调用。
 - 扩展功能,如取消请求、缓存请求等。