侧边栏壁纸
  • 累计撰写 225 篇文章
  • 累计创建 275 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

如何优雅地管理Axios拦截器(Interceptors)

DGF
DGF
2024-06-18 / 0 评论 / 0 点赞 / 22 阅读 / 0 字

Axios 拦截器(Interceptors)允许你在请求发出之前或响应接收之后执行一些操作。它们对于统一处理请求和响应(如添加认证令牌、处理错误等)非常有用。下面是一个简单的示例:

// interceptor.js  
import axios from 'axios';
 
// 请求拦截器,用于添加认证令牌等  
const requestInterceptor = axios.interceptors.request.use(
  config => {
    // 这里可以添加你的请求处理逻辑  
    return config;
  },
  error => {
    // 这里处理请求过程中发生的错误  
    return Promise.reject(error);
  }
);
 
// 响应拦截器,用于处理服务器返回的状态码和数据格式  
const responseInterceptor = axios.interceptors.response.use(
  response => {
    // 这里可以处理响应数据,例如统一的数据格式化  
    return response;
  },
  error => {
    // 这里处理响应过程中发生的错误,例如状态码检查  
    return Promise.reject(error);
  }
);
 
// 当不再需要这些拦截器时,可以这样解除注册  
function removeInterceptors() {
  axios.interceptors.request.eject(requestInterceptor);
  axios.interceptors.response.eject(responseInterceptor);
}
 
export default {
  removeInterceptors,
};

那么如何优雅地管理 Axios 拦截器呢?

注册拦截器

// 注册请求拦截器  
axios.interceptors.request.use()  
// 注册响应拦截器  
axios.interceptors.response.use()  

移除拦截器

当不再需要特定拦截器时,要移除它,以避免内存泄漏和不必要的处理。

// 移除请求拦截器  
axios.interceptors.request.eject()  
// 移除响应拦截器  
axios.interceptors.response.eject()  

组织代码

将拦截器相关的代码放在单独的模块或文件中,以便于管理和维护。对于复杂的逻辑,可以拆分成多个小函数,每个函数负责一个特定的任务。

// complexInterceptor.js  
import axios from 'axios';
 
// 这个函数负责添加认证令牌  
function addAuthToken() {
  return function (config) {
    if (localStorage.getItem('token')) {
      config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
    }
    return config;
  };
}
 
// 这个函数负责格式化请求数据  
function formatRequestData() {
  return function (config) {
    // 可以根据需要对 config.data 进行转换  
    if (config.method === 'POST' && config.url.endsWith('/someSpecialEndpoint')) {
      config.data = JSON.stringify(config.data);
    }
    return config;
  };
}
 
// 这个函数负责格式化响应数据  
function formatResponseData() {
  return function (response) {
    // 可以根据需要对 response.data 进行转换  
    if (response.config.url.endsWith('/anotherSpecialEndpoint')) {
      response.data = JSON.parse(response.data);
    }
    return response;
  };
}
 
// 这个函数负责处理请求过程中出现的错误  
function handleRequestError() {
  return function (error) {
    console.error('Request failed:', error);
    return Promise.reject(error);
  };
}
 
// 这个函数负责处理响应过程中出现的错误  
function handleResponseError() {
  return function (error) {
    if (error.response) {
      // 这里可以处理各种 HTTP 状态码  
      switch (error.response.status) {
        case 401:
          // 未授权,可能需要重新登录  
          break;
        case 403:
          // 禁止访问,权限不足  
          break;
        case 500:
          // 服务器内部错误  
          break;
        default:
          // 其他错误处理  
          break;
      }
    } else if (error.request) {
      // 这里处理网络问题,例如请求已发送但没有收到响应  
      console.error('Network error:', error.request);
    } else {
      // 这里处理其他类型的错误,例如配置请求时出错  
      console.error('Error in request configuration:', error.message);
    }
    return Promise.reject(error);
  };
}
 
export default function registerInterceptor() {
  const requestInterceptor = axios.interceptors.request.use(
    addAuthToken(),
    handleRequestError()
  );
  
  const responseInterceptor = axios.interceptors.response.use(
    formatResponseData(),
    handleResponseError()
  );
  
  // 返回一个函数以取消拦截器注册  
  return () => {
    axios.interceptors.request.eject(requestInterceptor);
    axios.interceptors.response.eject(responseInterceptor);
  };
}

错误处理

  • 在拦截器中提供错误处理逻辑,例如,当发生错误时返回一个 Promise.reject()
  • 在调用链的最后,使用 .catch() 处理所有未在拦截器中处理的错误。

优先级和顺序

  • 考虑拦截器的注册顺序,因为它们的执行顺序就是注册的顺序。
  • 如果有多个拦截器,决定它们之间的优先级,以便于正确处理请求和响应。

可配置性和可重用性

  • 创建可配置的拦截器,以便于根据不同情况动态配置行为。
  • 如果有多个相似的拦截器,考虑抽象出一个通用的拦截器,通过参数来配置其行为。

测试

  • 写单元测试来保证拦截器的行为符合预期。
  • 测试拦截器是否正确地处理了各种情况,如成功请求、失败请求等。
0

评论区