Vue路由切换 & Axios接口取消重复请求

简介: Vue路由切换 & Axios接口取消重复请求

本文已参与[新人创作礼]活动,一起开启掘金创作之路

在日常前端开发中, 经常会遇到频繁发起的重复请求, 会给服务器及网络造成不必要的压力, 可通过取消重复请求解决

场景

  • 订单数据条件筛选查询
  • 表单提交按钮频繁点击
  • 路由页面切换请求未取消

解决方案

在每个请求发起的时候存储当前存储的标记在一个数组或Map中, 针对每个请求的时候在请求拦截中查询是否重复, 如果已重复则取消历史中重复的请求, 再发起当前请求, 如果没有重复, 则添加存储标记并正常请求, 已请求完成的清除存储标记

axios中如何取消请求

  1. 可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
     // 处理错误
  }
});
axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');
  1. 还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});
// cancel the request
cancel();

项目中封装使用

基本变量定义

// 是否取消重复请求开关
const cancelDuplicated = true
// 存储每个请求中的map
const pendingXHRMap = new Map()
// 取消请求类型定义 便于后期对此类型不做异常处理
const REQUEST_TYPE = {
  DUPLICATED_REQUEST: 'duplicatedRequest'
}

设置重复标记的函数

const duplicatedKeyFn = (config) => {
  // 可在此设置用户自定义其他唯一标识 默认按请求方式 + 请求地址
  return `${config.method}${config.url}`
}

添加到请求记录

const addPendingXHR = (config) => {
  if (!cancelDuplicated) {
    return
  }
  const duplicatedKey = JSON.stringify({
    duplicatedKey: duplicatedKeyFn(config),
    type: REQUEST_TYPE.DUPLICATED_REQUEST
  })
  config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
    if (duplicatedKey && !pendingXHRMap.has(duplicatedKey)) {
      pendingXHRMap.set(duplicatedKey, cancel)
    }
  })
}

删除请求记录

const removePendingXHR = (config) => {
  if (!cancelDuplicated) {
    return
  }
  const duplicatedKey = JSON.stringify({
    duplicatedKey: duplicatedKeyFn(config),
    type: REQUEST_TYPE.DUPLICATED_REQUEST
  })
  if (duplicatedKey && pendingXHRMap.has(duplicatedKey)) {
    const cancel = pendingXHRMap.get(duplicatedKey)
    cancel(duplicatedKey)
    pendingXHRMap.delete(duplicatedKey)
  }
}

axios中使用

// 请求拦截处理
axios.interceptors.request.use(config => {
    removePendingXHR(config)
    addPendingXHR(config)
    ...
    return config
})
// 响应拦截处理
axios.interceptors.response.use(response => {
    removePendingXHR(response.config)
    ...
}, error => {
    // 如果是取消请求类型则忽略异常处理
    let isDuplicatedType;
    try {
      const errorType = (JSON.parse(error.message) || {}).type
      isDuplicatedType = errorType === REQUEST_TYPE.DUPLICATED_REQUEST;
    } catch (error) {
      isDuplicatedType = false
    }
    if (!isDuplicatedType) {
        // 其他异常处理
    }
})

Vue中当路由切换页面的时候,将上一个页面的所有请求取消

router.beforeEach((to, from, next) => {
    // 遍历pendingMap,将上一个页面的所有请求cancel掉
    pendingXHRMap.forEach((cancel) => {
        cancel();
    });
    pendingXHRMap.clear()
})

总结

本文主要介绍了在日常前端开发中, 遇到各种情况下频繁发起的重复请求, 会给服务器及网络造成不必要的压力, 可通过取消重复请求解决。

参考

axios官网取消请求

如何优雅的解决”重复请求“问题


目录
相关文章
|
2月前
|
JavaScript
Vue中Axios网络请求封装-企业最常用封装模式
本教程介绍如何安装并配置 Axios 实例,包含请求与响应拦截器,实现自动携带 Token、错误提示及登录状态管理,适用于 Vue 项目。
114 1
|
10月前
|
前端开发 JavaScript Java
前端解决axios请求的跨域问题【2步完成】
本文介绍如何通过前端配置解决跨域问题,主要针对Vue项目中的`vite.config.js`文件进行修改。作者在联调过程中遇到跨域报错
551 1
|
11月前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
633 3
|
JavaScript 前端开发 Java
SpringBoot项目的html页面使用axios进行get post请求
SpringBoot项目的html页面使用axios进行get post请求
219 2
|
资源调度 JavaScript 前端开发
路由管理:Vue Router的使用和配置技巧
【10月更文挑战第21天】路由管理:Vue Router的使用和配置技巧
275 3
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
1446 4
|
JavaScript API
vue 批量自动引入并注册组件或路由等等
【10月更文挑战第12天】 vue 批量自动引入并注册组件或路由等等
|
Python
axios的get请求传入数组参数
【10月更文挑战第11天】 当使用 `axios` 发送包含数组参数的 GET 请求时,默认的序列化方式可能与后端(如 Django)不兼容,导致无法正确获取数组参数。解决方案是通过 `paramsSerializer` 指定自定义序列化函数,或使用 `qs` 库来格式化数组参数,确保前后端一致。示例代码展示了如何使用 `qs` 库设置 `arrayFormat` 为 `"repeat"`,以符合 Django 的解析要求。
519 2
|
JavaScript 前端开发 API
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
vue3中常用插件的使用方法:按需引入自定义组件,自动导入依赖包,自动生成路由,自动生成模拟数据
2078 0
|
JavaScript 前端开发 UED
vue中vue-router路由懒加载(按需加载)的作用以及常见的实现方法
vue中vue-router路由懒加载(按需加载)的作用以及常见的实现方法
641 1
下一篇
oss云网关配置