axios防重复提交

场景

用户在进行新增操作(比如新增菜单)。如果快速点击多次新增按钮,可能照成的情况就是新增了多条记录。一般可以通过在点击的时候,先禁用新增按钮,然后等本次操作完了,再解除禁用。不过,使用axios有更加优雅的实现方式。

axios防重复提交

思路

先说下思路:在进行axios提交操作的时候,把本次请求做一个标记,保存到一个数组中。等请求结束了,就从这个数组中,移除请求标记。所以,如果有两个完全一样的请求过来,那么后来的请求,就会发现在这个数组中,已经有了该标记,那么就在axios中取消本次请求。

具体实现

在我的代码中,已经对axios进行了统一的封装在http.js中了,所以,只需要在http.js中实现就好了:
首先定义一个数组来存请求标记,以及定义一个取消axios请求的对象:

// 请求列表(防重复提交)
let requestList = [];
let cancelToken = axios.CancelToken;

然后确定请求标记:这里我采用的就是请求的url+请求参数+请求方式,组合成一个字符串,作为请求标记,在request拦截器中,代码如下:

axios.interceptors.request.use(
    config => {
    
    

        //防止重复提交(如果本次是重复操作,则取消,否则将该操作标记到requestList中)
        config.cancelToken = new cancelToken((cancel) => {
    
    
            let requestFlag = JSON.stringify(config.url) + JSON.stringify(config.data) + '&' + config.method;
            if (requestList.includes(requestFlag)) {
    
    //请求标记已经存在,则取消本次请求,否则在请求列表中加入请求标记
                cancel();//取消本次请求
            } else {
    
    
                requestList.push(requestFlag);
            }
        });

        return config;
    },
    error => {
    
    
        return Promise.reject(err);
    }
);

最后,在请求结束中,请请求标记移除,在response拦截器中,代码如下:

axios.interceptors.response.use(
    response => {
    
    
        //请求返回后,将请求标记从requestList中移除
        let requestFlag = JSON.stringify(response.config.url) + JSON.stringify(response.config.data) + '&' + response.config.method;
        requestList.splice(requestList.findIndex(item => item === requestFlag), 1);

        return response;
    },
    error => {
    
    
        //置空请求列表
        requestList.length = 0;
        
        return Promise.reject(error)
    }
)

补充

如果在系统中,真的存在这种两个请求的url、参数、请求方式都一模一样,并且还要在用户的一个操作中向后端请求(我倒是没有遇到过这种情况),这个方式也是有解决方案的。在上面介绍中,请求标记,使用的方式是:url+请求参数+请求方式。那么这个时候在请求参数中,在加一个特别的参数就可以了,当然这个参数只是为了防止重复提交中,请求标记的确定,并没有其他作用。当然,也可以另想一个办法来实现这个请求标记。总之,这种需求,几乎不会出现。

猜你喜欢

转载自blog.csdn.net/fyk844645164/article/details/101064597