項(xiàng)目使用了Axios,如何避免服務(wù)器卡頓時(shí)后用戶可能重復(fù)提交表單的問(wèn)題.
看axios文檔提供了CancelToken來(lái)取消請(qǐng)求的方法,但是不知道如何使用,
求大神指點(diǎn)一下
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;
}
});
},
我是用變量控制的
引自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();
我沒(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);
};`
這個(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)
})
}
}
}
額,對(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)題前端要做的事情。
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
北大青鳥(niǎo)中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過(guò)二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。