Axios利用拦截器处理重复请求

我们在开发时 经常会遇到类似场景

  • 提交表单时,连续点击提交表单,导致后台重复处理
  • 写一个连续点击脚本,不停发送请求,并发量导致服务器瘫痪

今天,我们解决类似问题:

一、重复请求

处理流程:

开始请求拦截响应拦截判断数组是否存在当前请求url如果存在cancelToken取消当次请求如果当次请求成功数组中清除当次请求url数组存储请求url开始请求拦截响应拦截

代码:

request.js

引入请求以及部分组件,并且定义一个变量用来存储请求url

import axios from 'axios'
import { Message, Notification } from 'element-ui'


let requestList = new Set() // 存储请求url

请求发出前,利用拦截器判断当前是否存在请求,如果存在利用cancelToken取消,反之添加到数组中

// 请求前拦截器
axios.interceptors.request.use(config => {
  // 利用cancelToken 取消当次请求
  config.cancelToken = new axios.CancelToken(e => {
  	// 在这里阻止重复请求,上个请求未完成时,相同的请求不会再次执行
  	requestList.has(config.url) ? e(`${location.host}${config.url}---重复请求被中断`) : requestList.add(config.url)
  })
  return config
}, error => {
  Message.error('未知错误')
  return Promise.reject(error)
})

利用响应拦截器,在这里处理已发送或者被动取消的请求
已发送请求无论成功与否,务必在数组中清除掉

这里根据需求处理:

  • 成功的业务逻辑
  • 取消的业务逻辑
  • 失败的业务逻辑
// 响应拦截器
axios.interceptors.response.use(response => {
  // 相同请求不得在600毫秒内重复发送,反之继续执行
  setTimeout(() => {
    requestList.delete(response.config.url)
  }, 600)
  // 请求成功业务逻辑
  if (response.data.code == '200') {
    return response.data
  } else {
    switch (response.data.code) {
      case 201:
        Message.warning('您提交的信息异常')
        break
      case 203:
        Notification({
          title: '提示',
          message: response.data.msg,
          type: 'error',
          showClose: true,
        })
        router.replace({path: '/login'})
        break;
      default:
        Message.error(response.data.msg)
    }
  }
}, error => {
  // 这里判断异常情况,如果axios.isCancel 为 true时,说明请求被取消
  if (axios.isCancel(error)) {
    // 请求取消
    console.warn(error)
    console.table([error.message.split('---')[0]], 'cancel')
  } else {
    // 请求失败
    if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
      Message.warning('请求超时')
    } else if (error.message == 'Network Error') {
      Message.error('网络连接异常,请重试')
    } else {
      Message.error('未知错误', error.message)
    }
   // 请求如果失败了,务必从列表里面删掉,否则请求拦截器会取消请求
   requestList.delete(error.config.url)
 }
  return Promise.reject(error)
})

总结:

  • 请求拦截器
    利用数组存储每次发出请求url,请求拦截器判断数组是否存在此次请求url,如果存在,调用cancelToken取消请求并且清除url,反之url添加到数组中
  • 响应拦截器
    本次请求不论成功与否,清除本次url记录,否则会拦截取消请求
注意:
可以使用同一个 cancel token 取消多个请求

效果:
在这里插入图片描述
至此,我们就成功拦截了重复请求

链接:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章