鍍金池/ 問(wèn)答/HTML/ axios 如何解決重復(fù)提交

axios 如何解決重復(fù)提交

項(xiàng)目使用了Axios,如何避免服務(wù)器卡頓時(shí)后用戶可能重復(fù)提交表單的問(wèn)題.
看axios文檔提供了CancelToken來(lái)取消請(qǐng)求的方法,但是不知道如何使用,
求大神指點(diǎn)一下

回答
編輯回答
病癮

https://www.npmjs.com/package... 借鑒別人的以及axios文檔,一個(gè)簡(jiǎn)單的方法

2017年9月23日 17:04
編輯回答
青裙

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(`創(chuàng)建失敗,服務(wù)器返回信息:${res.msg}`, '系統(tǒng)通知', { confirmButtonText: '確定', type: 'error' })
                            return false;
                        }
                        this.$notify({ title: '系統(tǒng)通知', message: '新建成功!', type: 'success' });
                        this.$router.go(-1);
                    })
                } else {
                    this.$alert('請(qǐng)勿重復(fù)提交 ; 等待返回信息', '系統(tǒng)通知', { confirmButtonText: '確定', type: 'error' })
                }
            } else {
                return false;
            }
        });
    },

我是用變量控制的

2018年3月27日 20:58
編輯回答
六扇門(mén)

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

使用 cancel token 取消請(qǐng)求
Axios 的 cancel token API 基于cancelable promises proposal,它還處于第一階段。
可以使用 CancelToken.source 工廠方法創(chuàng)建 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 {
    // 處理錯(cuò)誤
  }
});

// 取消請(qǐng)求(message 參數(shù)是可選的)
source.cancel('Operation canceled by the user.');

還可以通過(guò)傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來(lái)創(chuàng)建 cancel token:

var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函數(shù)接收一個(gè) cancel 函數(shù)作為參數(shù)
    cancel = c;
  })
});

// 取消請(qǐng)求
cancel();
2018年8月30日 03:38
編輯回答
帥到炸

我沒(méi)用 axios自帶xxx ,直接在攔截器里面 用這個(gè)方法吧 模擬session 做一個(gè) 請(qǐng)求有效性數(shù)組

具體實(shí)現(xiàn)如:`// 設(shè)置緩存時(shí)間 和緩存請(qǐng)求數(shù)組
var requestUrl = [], saveTime = 1000;
http 攔截器中處理:
const Interceptor = function (obj,callback) {

if (obj.method === 'POST') {
    // 篩選在緩存時(shí)間內(nèi)未過(guò)期請(qǐng)求 重新賦值緩存請(qǐng)求數(shù)組 新數(shù)組與當(dāng)前請(qǐng)求url 匹配
    // 如果有相等項(xiàng) 則判斷為重復(fù)提交的請(qǐng)求 直接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 + '請(qǐng)求重復(fù) 中斷請(qǐng)求!');
        return;
    }
    let item = { url: obj.url, setTime: new Date().getTime() };
    requestUrl.push(item);
}
callback(obj);

};`

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

2018年1月8日 05:32
編輯回答
安于心

用個(gè) 布爾變量(例如:canPost) 就可以了啊,判斷用戶提交后,沒(méi)成功之前將canPost置為 false ,每次請(qǐng)求的時(shí)候都會(huì)判斷這個(gè)變量,如果變量為 false 直接return就好了

2017年12月15日 19:43
編輯回答
失心人

這個(gè)問(wèn)題也困擾我很久。原生的倒是有abort()實(shí)現(xiàn)。。網(wǎng)上關(guān)于axios庫(kù)取消上次請(qǐng)求的例子太少。官方文檔說(shuō)得也太簡(jiǎn)潔。本屌水平太爛、看了一天也沒(méi)個(gè)頭緒。后面這試下那試下。倒是出來(lái)了。。希望對(duì)樓主有幫助。

我的是VUE項(xiàng)目。。依據(jù)官方。。。還可以通過(guò)傳遞一個(gè) executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來(lái)創(chuàng)建 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)
         })      
    }
}

}

2017年7月9日 03:23
編輯回答
尋仙

額,對(duì)于你遇到的問(wèn)題

如何避免服務(wù)器卡頓時(shí)后用戶可能重復(fù)提交表單的問(wèn)題.

也許你想要的答案是 - 如何不發(fā)重復(fù)的請(qǐng)求

那么,如何不發(fā)重復(fù)的請(qǐng)求呢?

最簡(jiǎn)單的辦法是,如果請(qǐng)求沒(méi)有返回(失敗或者成功),禁止再提交。在前端,可以disable提交按鈕,或者disable提交函數(shù), 具體可以參考各種手機(jī)驗(yàn)證碼發(fā)送按鈕的設(shè)計(jì)。從根本上解決用戶重復(fù)提交。

這個(gè)辦法還有一個(gè)必須要注意的是,如果服務(wù)器返回時(shí)間太長(zhǎng),用戶等待可能會(huì)比較久,體驗(yàn)會(huì)很差。所以,前端必須要設(shè)置timeout。

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

不管服務(wù)器是否卡頓,超過(guò)1秒鐘,axios自動(dòng)結(jié)束。用戶又可以再點(diǎn)擊提交了。當(dāng)然,記得在發(fā)現(xiàn)timeout之后調(diào)用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.');

以上,就是解決這個(gè)問(wèn)題前端要做的事情。

2018年5月2日 00:30