首页 > 其他分享 >axios如何取消请求,其原理是什么?

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

时间:2023-08-21 19:05:55浏览次数:32  
标签:Axios 请求 取消 source axios CancelToken


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

  1. 创建一个 CancelToken 的实例,它有一个 executor 函数,可以通过调用 executor 参数中的 cancel 函数来取消请求。
  2. 在 axios 请求配置中指定 cancelToken 属性,将 CancelToken 实例传递进去。
  3. 当我们需要取消请求时,调用 CancelToken 实例的 cancel() 方法即可取消对应的请求。
  4. axios 检测到配置的 cancelToken 被取消,就会取消掉这个请求,并在错误回调中返回一个 Cancel 错误。
    axios 内部会监听 cancelToken 实例的 cancel 信号,一旦触发就会跳出队列,取消对应请求的执行。
    示例代码:
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 实例,以便于应用中的多个组件共享相同的配置和取消令牌。
// axiosInstance.js
import axios from 'axios';

const instance = axios.create();

export default instance;
  1. 在组件中使用这个封装的 Axios 实例,并结合组件的状态管理来处理取消请求的逻辑。
// 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 实例,同样可以让多个组件共享相同的配置和取消令牌。
// axiosInstance.js
import axios from 'axios';

const instance = axios.create();

export default instance;
  1. 在组件中使用这个封装的 Axios 实例,并结合组件的状态管理来处理取消请求的逻辑。
<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(),从而使网络请求停止并抛出取消错误。这个机制允许有效地取消正在进行的请求,避免不必要的数据传输和处理。


标签:Axios,请求,取消,source,axios,CancelToken
From: https://blog.51cto.com/u_14196886/7178192

相关文章

  • RTSP/Onvif流媒体服务器EasyNVR安防视频平台一直提示网络请求失败的问题解决方案
    EasyNVR平台优秀的视频能力在于通过RTSP/ONVIF协议,将前端接入设备的音视频资源进行采集,并转码成适合全平台、全终端分发的视频流格式,包括RTMP、RTSP、FLV、HLS、WebRTC等格式。有用户反馈,EasyNVR使用过程中,突然提示网络请求失败,视频也无法播放,请求我们协助排查。此前我......
  • 慢速HTTP请求DOS攻击的解决方法
    在HTTP中间件中设置连接超时时间可以提高服务器的安全性和性能。下面是几种常见的HTTP中间件和如何设置连接超时时间的示例:ApacheHTTP服务器:在Apache的配置文件(如httpd.conf)中可以使用Timeout指令设置连接超时时间。例如,要将连接超时时间设置为30秒,您可以添加以下行:Timeout30Ngi......
  • Vue 中请求同步执行解决方案
    有很多小伙伴在使用Vue的时候都会遇到一种情况,form表单修改回显时,某个下拉框里的内容回显乱码,这是因为Vue是的请求方法是异步请求:简单来说,form表单内容先获取了出来,而项目阶段的下拉框随后才获取出来//表单<el-col:span="12"> <el-form-item:label="$t('项目阶段')"prop=......
  • Kettle实例(获取Token并带入请求接口拉取数据到本地)
    背景      近期工作中遇到许多需要协同的表单文档被放到云文档,那么我们本地做数据分析就需要先抽取云文档实时数据到本地数据库,根据接口文档我们需要先获取Token,再将返回值带到接口中发起请求拉取数据,因为在做数据仓库项目调度用到过Kettle,想到RESTclient组件可以完成这......
  • HTTP中的Get和Post请求到底有什么区别?
    一、HTTP中的Get和Post请求到底有什么区别?1.HTTP诞生,是为了解决浏览器与服务器之间的通讯协议,GET用于读取资源,POST用于提交表单。2.后来被扩充到接口格式的定义,GET和Post作为接口的请求方式。二、协议核心四部分:Method:get/postUrl:UrlHeader:{}Body:{......
  • 对 uniapp 网络请求 uni.request 进行封装
    前言uniapp是一款基于Vue.js框架的跨平台开发工具,可以将代码编译成H5、小程序、App等不同平台的应用。在进行uniapp开发时,网络请求是必不可少的环节。为了方便开发,我们可以封装一些网络请求方法,以便在多个页面中复用,并且可以统一处理错误信息等问题,提高开发效率和代码质量。本文将......
  • 软件测试|测试平台开发-Flask 入门:Flask HTTP请求详解
    简介上一篇文章我们介绍了flask的基本使用,编写了flask的第一个脚本。在本文中,我们将详细介绍如何使用Flask进行HTTP请求。我们将学习如何创建Flask应用程序,并通过不同的HTTP方法(GET、POST、PUT、DELETE等)发送请求。app.route()要使用不同的http方法发送请求,我们要先了解flask是如何......
  • python+playwright 学习-75 playwright 通过浏览器发送post请求
    前言page.goto()可以通过浏览器直接发get请求,playwright也可以支持通过浏览器发送post请求。page.goto()使用page.goto()访问网站的时候,实际上是有返回值的,可以获取到response对象fromplaywright.sync_apiimportsync_playwright,expectwithsync_playwright()asp:......
  • 使用RestTemplate 接收请求返回值中的泛型
    现有一个请求返回值的格式为:{ "success":true, "message":"", "code":200, "result":{ "returnCode":"03AD", "returnMsg":"AD3", "qrcode":"https://xxxxx......
  • python+playwright 学习-74 set_extra_http_headers设置浏览器请求头部
    前言大部分网站保存登录状态是用cookies,也有个别网站是在请求头部添加token实现保存登录。playwright可以使用set_extra_http_headers()方法设置浏览器请求头部参数set_extra_http_headers()方法设置头部参数headers,字典键值对fromplaywright.sync_apiimportsync_pla......