专业编程基础技术教程

网站首页 > 基础教程 正文

前端知识点-axios 的拦截器原理及应用,并简单手写核心逻辑

ccvgpt 2025-05-08 17:05:52 基础教程 2 ℃

Axios 拦截器允许在请求和响应阶段插入处理逻辑。以下是其原理、实现及优雅应用:

拦截器原理

  1. 队列结构:请求和响应拦截器分别存储在队列中,请求拦截器在发送请求前执行,响应拦截器在接收响应后执行。
  2. Promise 链:通过构建 Promise 链,依次执行拦截器处理函数。请求拦截器按添加顺序执行,响应拦截器同样按添加顺序执行。
  3. 错误处理:任一拦截器返回 rejected Promise 会跳过后续拦截器,直接进入错误处理。

手写核心逻辑

class InterceptorManager {
  constructor() {
    this.handlers = [];
  }

  use(fulfilled, rejected) {
    this.handlers.push({ fulfilled, rejected });
  }
}

class Axios {
  constructor() {
    this.interceptors = {
      request: new InterceptorManager(),
      response: new InterceptorManager(),
    };
  }

  request(config) {
    let chain = [this.dispatchRequest, undefined]; // 初始链

    // 请求拦截器按顺序插入到链首
    this.interceptors.request.handlers.reverse().forEach(interceptor => {
      chain.unshift(interceptor.fulfilled, interceptor.rejected);
    });

    // 响应拦截器按顺序添加到链尾
    this.interceptors.response.handlers.forEach(interceptor => {
      chain.push(interceptor.fulfilled, interceptor.rejected);
    });

    let promise = Promise.resolve(config);

    while (chain.length) {
      promise = promise.then(chain.shift(), chain.shift());
    }

    return promise;
  }

  dispatchRequest(config) {
    // 模拟实际请求
    return new Promise(resolve => {
      setTimeout(() => resolve({ data: config.url, status: 200 }), 100);
    });
  }
}

// 使用示例
const axios = new Axios();

// 添加请求拦截器
axios.interceptors.request.use(config => {
  console.log('请求拦截器1');
  config.headers = { Authorization: 'Bearer token' };
  return config;
});

axios.interceptors.request.use(config => {
  console.log('请求拦截器2');
  return config;
});

// 添加响应拦截器
axios.interceptors.response.use(response => {
  console.log('响应拦截器1');
  return response.data; // 返回处理后的数据
});

axios.interceptors.response.use(response => {
  console.log('响应拦截器2');
  return response;
});

axios.request({ url: '/api/data' })
  .then(data => console.log('成功:', data))
  .catch(err => console.error('失败:', err));

拦截器应用场景

  1. 请求处理
  2. 添加认证头:config.headers.Authorization = 'Bearer token'
  3. 请求数据格式化:转换数据格式或加密
  4. 响应处理
  5. 统一错误处理:检查状态码,处理 401 跳转登录
  6. 数据解析:提取响应数据,如 return response.data
  7. 全局Loading
  8. 请求前显示 Loading,响应后隐藏

优雅实践建议

  1. 模块化:将拦截器拆分到独立文件,便于维护。
// auth-interceptor.js
export function requestAuth(config) {
  config.headers.Auth = 'xxx';
  return config;
}

错误处理:统一在响应拦截器中处理错误。

前端知识点-axios 的拦截器原理及应用,并简单手写核心逻辑

axios.interceptors.response.use(null, err => {
  if (err.response.status === 401) {
    redirectToLogin();
  }
  return Promise.reject(err);
});
  1. 避免副作用:拦截器应保持纯净,避免修改外部状态。
  2. 取消拦截器:通过 eject 移除不必要的拦截器。
const interceptor = axios.interceptors.request.use(...);
axios.interceptors.request.eject(interceptor);

执行顺序示例

请求拦截器1 → 请求拦截器2 → 发送请求 → 响应拦截器1 → 响应拦截器2 → 最终结果

通过合理使用拦截器,可提升代码复用性,统一管理请求/响应逻辑,使代码更简洁易维护。

Tags:

最近发表
标签列表