前端接口防止重复请求实现方案

众所周知,我们在项目开发过程中难免会遇到重复请求的处理(用户快速点击按钮,触发调用接口操作),下面是实现防止重复请求的实现方案
  • 方案1

    这个方案是最容易想到也是最朴实无华的一个方案:通过使用axios拦截器,在请求拦截器中开启全屏Loading,然后在响应拦截器中将Loading关闭。

    在这里插入图片描述

    这个方案固然已经可以满足我们目前的需求,但不管三七二十一,直接搞个全屏Loading还是不太美观,何况在目前项目的接口处理逻辑中还有一些局部Loading,就有可能会出现Loading套Loading的情况,两个圈一起转,头皮发麻。

  • 方案2

    加Loading的方案不太友好,而对于同一个接口,如果传参都是一样的,一般来说都没有必要连续请求多次吧。那我们可不可以通过代码逻辑直接把完全相同的请求给拦截掉,不让它到达服务端呢?这个思路不错,我们说干就干。

    首先,我们要判断什么样的请求属于是相同请求

    一个请求包含的内容不外乎就是请求方法地址参数以及请求发出的页面hash。那我们是不是就可以根据这几个数据把这个请求生成一个key来作为这个请求的标识呢?

    // 根据请求生成对应的key
    function generateReqKey(config, hash) {
         
         
        const {
         
          method, url, params, data } = config;
        return [method, url, JSON.stringify(params), JSON.stringify(data), hash].join("&");
    }
    

    有了请求的key,我们就可以在请求拦截器中把每次发起的请求给收集起来,后续如果有相同请求进来,那都去这个集合中去比对,如果已经存在了,说明就是一个重复的请求,我们就给拦截掉。当请求完成响应后,再将这个请求从集合中移除。合理,nice!

    具体实现如下:

    import axios from 'axios';
    
    const instance = axios.create({
         
         
      baseUrl: '/api/',
    });
    
    // 根据请求生成对应的 key
    function generateReqKey(config, hash) {
         
         
      const {
         
          method, url, params, data } = config;
      return [method, url, JSON.stringify(params), JSON.stringify(data), hash].join('&');
    }
    
    // 存储已发送但未响应的请求
    const pendingRequest = new Set();
    
    // 添加请求拦截器
    instance.interceptors.request.use(function (config) {
         
         
      const hash = location.hash;
      // 生成请求 Key
      const reqKey = generateReqKey(config, hash);
      if (pendingRequest.has(reqKey)) {
         
         
        return Promise.reject(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值