You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目中Axios客户端取消请求功能失效问题

解决Axios通用请求中取消上一次请求的问题

你当前的代码没实现取消上一次请求的核心原因是:创建CancelToken时只是在executor函数里return了取消函数,但没有把它保存下来,导致无法在新请求发起时调用这个函数去取消旧请求。

解决方案

需要在axios工具类里维护一个全局的取消函数变量,每次发起新请求前先取消上一次未完成的请求,同时保存当前请求的取消函数。

修改后的axiosClient.js

import axios from 'axios';
import { BASEURL } from '../config/endpoints';
import { getToken } from '../Auth';

const CancelToken = axios.CancelToken;
// 全局存储上一次请求的取消函数
let cancelPreviousRequest = null;

export function getRequest(URL, payload={}, headers={}) {
    return apiRequest(URL, payload, "get", headers);
}

export async function apiRequest(endPoint, data, method, headers, requestOptions = {}) {
    return new Promise(async (resolve, reject) => {
      // 发起新请求前,先取消上一次未完成的请求
      if (cancelPreviousRequest) {
        cancelPreviousRequest('请求已被取消,因为发起了新请求');
        cancelPreviousRequest = null;
      }

      const token = getToken();
      // 合并传入的headers,避免覆盖默认配置
      const requestHeaders = {
        Accept: 'application/json',
        ...headers
      };
      
      if (data instanceof FormData) {
        requestHeaders['Content-Type'] = 'multipart/form-data';
      } else {
        requestHeaders['Content-Type'] = 'application/json';
      }
  
      if (token) {
        requestHeaders['access_token'] = token;
      }
  
      axios({
        method: method,
        url: endPoint,
        headers: requestHeaders,
        data: data,
        cancelToken: new CancelToken(function executor(c) {
          // 保存当前请求的取消函数
          cancelPreviousRequest = c;
        })
      }).then((result) => {
        // 请求完成后清空取消函数
        cancelPreviousRequest = null;
        resolve(result);
      }).catch((error) => {
        // 主动取消请求时,清空取消函数
        if (axios.isCancel(error)) {
          cancelPreviousRequest = null;
        }
        reject(error);
      });
    });
  }

组件中的使用示例(针对多次触发请求的场景)

比如搜索关键词变化时触发请求:

// My component Users.js
import axios from 'axios';
import { useState, useEffect } from 'react';
import { getRequest } from './axiosClient';
import { URL } from '../config/endpoints';

async function getUsers(url) {
    try {
        const response = await getRequest(url);
        // 处理响应数据
        console.log('用户数据:', response.data);
    } catch (error){
        // 区分取消请求的错误和其他错误
        if (axios.isCancel(error)) {
            console.log('请求被取消:', error.message);
            return;
        }
        // 其他错误处理逻辑
        console.error('请求失败:', error);
    }
}

function Users() {
    const [searchKeyword, setSearchKeyword] = useState('');

    useEffect( ()=>{
        // 根据关键词拼接请求URL
        getUsers(`${URL}?keyword=${searchKeyword}`);
    },[searchKeyword]);

    return (
        <input 
            type="text" 
            value={searchKeyword}
            onChange={(e) => setSearchKeyword(e.target.value)}
            placeholder="搜索用户"
        />
    );
}

export default Users;

关键说明

  • 全局变量cancelPreviousRequest负责存储上一次请求的取消函数,每次新请求发起前都会检查并调用它取消旧请求。
  • 请求成功完成或被主动取消后,必须清空这个变量,避免后续请求误取消无关请求。
  • 在组件的错误捕获中,用axios.isCancel(error)可以判断是否是主动取消的请求,方便做针对性处理(比如不用提示错误信息)。

内容的提问来源于stack exchange,提问作者Ram Chander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:52:59