如何封装axios和取消重复请求

1. 创建基础的 axios 实例

首先,创建一个基础的 axios 实例,并设置一些通用的配置,比如基础 URL、超时时间等。

javascript 复制代码
// src/utils/axios.js
import axios from 'axios';

const instance = axios.create({
  baseURL: 'https://api.example.com', // 替换为你的API地址
  timeout: 10000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json',
  },
});

export default instance;

2. 封装请求方法

封装常用的 HTTP 请求方法(如 GET、POST、PUT、DELETE),以便在项目中复用。

javascript 复制代码
// src/utils/request.js
import instance from './axios';

// GET 请求
export const get = (url, params = {}) => {
  return instance.get(url, { params });
};

// POST 请求
export const post = (url, data = {}) => {
  return instance.post(url, data);
};

3. 使用拦截器处理请求和响应

利用 axios 的拦截器功能,可以在请求发送前和响应返回后进行一些全局处理,比如添加请求头token、处理响应错误等。比如状态码统一管理

常见状态码 HTTP状态码:如200(成功)、203(重定向),400(请求错误)、401(未授权)403(授权失败)、404(未找到)、500(服务器错误)等。

javascript 复制代码
// 请求拦截器
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);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 对响应数据做点什么
    return response.data;
  },
  (error) => {
    // 对响应错误做点什么
    if (error.response) {
      // 服务器响应了状态码, 但不是2xx
      console.error(`Error ${error.response.status}: ${error.response.data}`);
    } else if (error.request) {
      // 请求已发出, 但没有收到响应
      console.error('No response received:', error.request);
    } else {
      // 设置请求时发生了错误
      console.error('Error setting up request:', error.message);
    }
    return Promise.reject(error);
  }
);

4. 取消重复请求

为了避免重复请求,可以使用 axiosCancelToken 功能。以下是一个示例,展示如何在组件卸载时取消请求。

javascript 复制代码
import axios from 'axios';

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

const pendingRequests = new Map(); // 用于存储正在进行的请求

// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 生成请求的唯一标识(可以根据 URL 和参数生成)
    const requestKey = `${config.url}?${new URLSearchParams(config.params).toString()}`;

    // 如果有相同的请求正在执行,取消之前的请求
    if (pendingRequests.has(requestKey)) {
      const cancelToken = pendingRequests.get(requestKey);
      cancelToken();
      pendingRequests.delete(requestKey); // 删除之前的请求
    }

    // 创建新的取消令牌
    const source = axios.CancelToken.source();

    // 存储新的请求
    pendingRequests.set(requestKey, source.cancel);

    // 将取消令牌附加到请求配置中
    config.cancelToken = source.token;

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  (response) => {
    // 响应成功后,移除对应的请求
    const requestKey = `${response.config.url}?${new URLSearchParams(response.config.params).toString()}`;
    pendingRequests.delete(requestKey);

    return response;
  },
  (error) => {
    // 响应失败后,移除对应的请求
    const requestKey = `${error.config.url}?${new URLSearchParams(error.config.params).toString()}`;
    pendingRequests.delete(requestKey);

    return Promise.reject(error);
  }
);

export default instance;

代码解释

pendingRequests 的作用

  • 用于存储正在进行的请求的取消令牌(CancelToken)。
  • 键(requestKey)是请求的唯一标识,通常是 URL 和参数的组合。

请求拦截器

  • 在每次请求发送前,检查是否有相同的请求正在执行。
  • 如果有,调用取消函数并移除之前的请求。
  • 创建新的取消令牌并存储到 pendingRequests 中。

响应拦截器

  • 在请求成功或失败后,移除对应的请求记录。

CancelToken 的原理是通过一个 Promise,当调用 cancel 方法时,会触发 Promisereject,从而中断请求。

相关推荐
To_OC5 小时前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC5 小时前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
天渺工作室6 小时前
实现一个adblock/adblock plus等浏览器广告拦截器检测插件
前端·javascript
阳光是sunny6 小时前
Vue 项目怎么做用户行为全链路监控?轻量插件方案详解
前端·面试·架构
ZhengEnCi6 小时前
Q04-Vite禁用CSS代码分割-解决生产环境样式加载顺序混乱问题
前端·vue.js·vite
九酒7 小时前
AI Agent 开发踩坑记:口播功能非得用 APP 原生实现吗?
前端·人工智能·agent
Jackson__7 小时前
做了一段时间的AI coding后,我终于搞清了 CLI 和 MCP 的区别
前端·agent·ai编程
IT_陈寒10 小时前
JavaScript项目实战经验分享
前端·人工智能·后端
用户479492835691511 小时前
6w star,GitHub 趋势第一的 Ponytail,这个agent插件到底在火什么
前端·后端
薛定喵的谔12 小时前
我开源了一个精致的 Next.js 博客模板:Skyplume
前端·前端框架·next.js