axios如何取消请求,其原理是什么?

axios 可以通过创建一个 CancelToken 来取消一个请求,基本原理是:

  1. 创建一个 CancelToken 的实例,它有一个 executor 函数,可以通过调用 executor 参数中的 cancel 函数来取消请求。
  2. 在 axios 请求配置中指定 cancelToken 属性,将 CancelToken 实例传递进去。
  3. 当我们需要取消请求时,调用 CancelToken 实例的 cancel() 方法即可取消对应的请求。
  4. axios 检测到配置的 cancelToken 被取消,就会取消掉这个请求,并在错误回调中返回一个 Cancel 错误。
    axios 内部会监听 cancelToken 实例的 cancel 信号,一旦触发就会跳出队列,取消对应请求的执行。
    示例代码:
javascript 复制代码
js
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user', {
  cancelToken: source.token
}).catch(function(thrown) {
  if(axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求
source.cancel('Operation canceled by the user.');

vue、React项目中如何取消

在基于 React 或 Vue 的应用中,可以通过封装 Axios 并结合组件的状态管理来实现取消请求的功能。下面分别介绍在 React 和 Vue 中如何实现这一点。

在 React 中的实现:

  1. 创建一个封装的 Axios 实例,以便于应用中的多个组件共享相同的配置和取消令牌。
javascript 复制代码
// axiosInstance.js
import axios from 'axios';

const instance = axios.create();

export default instance;
  1. 在组件中使用这个封装的 Axios 实例,并结合组件的状态管理来处理取消请求的逻辑。
js 复制代码
// YourComponent.js
import React, { useState } from 'react';
import axiosInstance from './axiosInstance';

function YourComponent() {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState(null);

  const source = axiosInstance.CancelToken.source();

  const fetchData = async () => {
    try {
      setLoading(true);
      const response = await axiosInstance.get('/api/some-endpoint', {
        cancelToken: source.token
      });
      setData(response.data);
      setLoading(false);
    } catch (error) {
      if (axiosInstance.isCancel(error)) {
        console.log('请求被取消:', error.message);
      } else {
        // 处理其他错误
      }
      setLoading(false);
    }
  };

  const cancelRequest = () => {
    source.cancel('请求被用户取消');
  };

  return (
    <div>
      {loading ? <p>Loading...</p> : <p>{data}</p>}
      <button onClick={fetchData}>Fetch Data</button>
      <button onClick={cancelRequest}>取消请求</button>
    </div>
  );
}

export default YourComponent;

在 Vue 中的实现:

  1. 创建一个封装的 Axios 实例,同样可以让多个组件共享相同的配置和取消令牌。
javascript 复制代码
// axiosInstance.js
import axios from 'axios';

const instance = axios.create();

export default instance;
  1. 在组件中使用这个封装的 Axios 实例,并结合组件的状态管理来处理取消请求的逻辑。
js 复制代码
<template>
  <div>
    <p v-if="loading">Loading...</p>
    <p v-else>{{ data }}</p>
    <button @click="fetchData">Fetch Data</button>
    <button @click="cancelRequest">取消请求</button>
  </div>
</template>

<script>
import axiosInstance from './axiosInstance';

export default {
  data() {
    return {
      loading: false,
      data: null,
      source: axiosInstance.CancelToken.source()
    };
  },
  methods: {
    async fetchData() {
      try {
        this.loading = true;
        const response = await axiosInstance.get('/api/some-endpoint', {
          cancelToken: this.source.token
        });
        this.data = response.data;
        this.loading = false;
      } catch (error) {
        if (axiosInstance.isCancel(error)) {
          console.log('请求被取消:', error.message);
        } else {
          // 处理其他错误
        }
        this.loading = false;
      }
    },
    cancelRequest() {
      this.source.cancel('请求被用户取消');
    }
  }
};
</script>

原理

Axios 取消请求的原理是基于底层网络请求库(如 XMLHttpRequest 或 Fetch)提供的中止机制。当调用取消令牌的 cancel 方法时,Axios 会触发中止底层的网络请求,从而终止正在进行的请求过程。

具体来说,以下是 Axios 取消请求的原理:

  1. 创建 CancelToken 对象: 在发起请求之前,可以通过 axios.CancelToken.source() 方法创建一个 CancelToken 对象,并获取其中的 token。这个 token 是一个用于标识该请求的令牌。

  2. 关联 CancelToken: 将创建的 CancelToken 对象中的 token 关联到请求的配置中,通过 cancelToken 参数。这告诉 Axios 在取消令牌触发时要取消这个请求。

  3. 取消请求: 当想要取消请求时,调用 CancelToken 对象中的 cancel 方法,并提供一个取消的原因。这会触发 Axios 内部的逻辑,导致底层的网络请求被中止。

  4. 捕获取消错误: 如果请求在取消前已经发出,Axios 会抛出一个名为 Cancel 的错误。可以使用 axios.isCancel(error) 来检查是否是取消错误。在 .catch 部分处理这个取消错误。

底层 XMLHttpRequest 和 Fetch API 都提供了终止请求的机制。当取消请求时,Axios 会调用底层网络请求的相应中止方法,例如 xhr.abort()fetch.abort(),从而使网络请求停止并抛出取消错误。这个机制允许有效地取消正在进行的请求,避免不必要的数据传输和处理。

相关推荐
尘中客1 小时前
放弃 Echarts?前端直接渲染后端高精度 SVG 矢量图流的踩坑记录
前端·javascript·echarts·前端开发·svg矢量图·echarts避坑
FreeBuf_1 小时前
Chrome 0Day漏洞遭野外利用
前端·chrome
小彭努力中1 小时前
199.Vue3 + OpenLayers 实现:点击 / 拖动地图播放音频
前端·vue.js·音视频·openlayers·animate
2501_916007471 小时前
网站爬虫原理,基于浏览器点击行为还原可接口请求
前端·javascript·爬虫·ios·小程序·uni-app·iphone
前端大波2 小时前
Sentry 每日错误巡检自动化:设计思路与上手实战
前端·自动化·sentry
Highcharts.js3 小时前
适合报表系统的可视化图表|Highcharts支持直接导出PNG和PDF
javascript·数据库·react.js·pdf
ZC跨境爬虫3 小时前
使用Claude Code开发校园交友平台前端UI全记录(含架构、坑点、登录逻辑及算法)
前端·ui·架构
慧一居士3 小时前
Vue项目中,何时使用布局、子组件嵌套、插槽 对应的使用场景,和完整的使用示例
前端·vue.js
叫我一声阿雷吧3 小时前
JS 入门通关手册(35):执行上下文、调用栈与作用域链深度解析
javascript·作用域链·js进阶·执行上下文·调用栈·变量提升·闭包原理
Можно3 小时前
uni.request 和 axios 的区别?前端请求库全面对比
前端·uni-app