axios 如何解决重复提交

发布于 2022-09-06 06:34:46 字数 99 浏览 7 评论 0

项目使用了Axios,如何避免服务器卡顿时后用户可能重复提交表单的问题.
看axios文档提供了CancelToken来取消请求的方法,但是不知道如何使用,
求大神指点一下

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

十二 2022-09-13 06:34:46

这个问题也困扰我很久。原生的倒是有abort()实现。。网上关于axios库取消上次请求的例子太少。官方文档说得也太简洁。本屌水平太烂、看了一天也没个头绪。后面这试下那试下。倒是出来了。。希望对楼主有帮助。

我的是VUE项目。。依据官方。。。还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token。。。。
export default {

data(){return {cancelTokenFn: null}},
methods: {
    cancelTokenDone () {
    
        const _this = this
        const CancelToken = axios.CancelToken
        
        this.cancelTokenFn && this.cancelTokenFn()
        this.cancelTokenFn = null
        
        axios.get('url', {cancelToken: new CancelToken(function executor(c) {
                                          _this.cancelTokenFn = c
                                       })})
         .then(function (response) {
             const data = response.data
             console.log(data)
         })
         .catch(function (error) {
             console.log(error)
         })      
    }
}

}

记忆之渊 2022-09-13 06:34:46

额,对于你遇到的问题

如何避免服务器卡顿时后用户可能重复提交表单的问题.

也许你想要的答案是 - 如何不发重复的请求

那么,如何不发重复的请求呢?

最简单的办法是,如果请求没有返回(失败或者成功),禁止再提交。在前端,可以disable提交按钮,或者disable提交函数, 具体可以参考各种手机验证码发送按钮的设计。从根本上解决用户重复提交。

这个办法还有一个必须要注意的是,如果服务器返回时间太长,用户等待可能会比较久,体验会很差。所以,前端必须要设置timeout。

var instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

不管服务器是否卡顿,超过1秒钟,axios自动结束。用户又可以再点击提交了。当然,记得在发现timeout之后调用cancel。

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // handle error
  }
});

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

以上,就是解决这个问题前端要做的事情。

风向决定发型 2022-09-13 06:34:46

引自https://www.kancloud.cn/yunye...最后面取消部分

使用 cancel token 取消请求
Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。
可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel();
春庭雪 2022-09-13 06:34:46

用个 布尔变量(例如:canPost) 就可以了啊,判断用户提交后,没成功之前将canPost置为 false ,每次请求的时候都会判断这个变量,如果变量为 false 直接return就好了

白云不回头 2022-09-13 06:34:46

goHold(subData) {

        this.$refs[subData].validate((valid) => {
            if (valid) {
                if (this.isOk) {
                    this.isOk = false;
                    this.$api.apiCommunication('xxx', this.subData, res => {
                        if (res.code != 2000) {
                            this.isOk = true;
                            this.$alert(`创建失败,服务器返回信息:${res.msg}`, '系统通知', { confirmButtonText: '确定', type: 'error' })
                            return false;
                        }
                        this.$notify({ title: '系统通知', message: '新建成功!', type: 'success' });
                        this.$router.go(-1);
                    })
                } else {
                    this.$alert('请勿重复提交 ; 等待返回信息', '系统通知', { confirmButtonText: '确定', type: 'error' })
                }
            } else {
                return false;
            }
        });
    },

我是用变量控制的

缱倦旧时光 2022-09-13 06:34:46

我没用 axios自带xxx ,直接在拦截器里面 用这个方法吧 模拟session 做一个 请求有效性数组

具体实现如:`// 设置缓存时间 和缓存请求数组
var requestUrl = [], saveTime = 1000;
http 拦截器中处理:
const Interceptor = function (obj,callback) {

if (obj.method === 'POST') {
    // 筛选在缓存时间内未过期请求 重新赋值缓存请求数组 新数组与当前请求url 匹配
    // 如果有相等项 则判断为重复提交的请求 直接return
    let nowTime = new Date().getTime();
    requestUrl = requestUrl.filter((item) => {
        return (item.setTime + saveTime) > nowTime;
    });
    let sessionUrl = requestUrl.filter((item) => {
        return item.url === obj.url;
    });
    if (sessionUrl.length > 0) {
        // console.log(obj.url + '请求重复 中断请求!');
        return;
    }
    let item = { url: obj.url, setTime: new Date().getTime() };
    requestUrl.push(item);
}
callback(obj);

};`

https://www.zhihu.com/questio...

╭⌒浅淡时光〆 2022-09-13 06:34:46

https://www.npmjs.com/package... 借鉴别人的以及axios文档,一个简单的方法

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文