小編給大家分享一下element-ui怎么防止重復提交,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
網(wǎng)站的建設成都創(chuàng)新互聯(lián)專注網(wǎng)站定制,經(jīng)驗豐富,不做模板,主營網(wǎng)站定制開發(fā).小程序定制開發(fā),H5頁面制作!給你煥然一新的設計體驗!已為成都咖啡廳設計等企業(yè)提供專業(yè)服務。
先說對話框(Dialog)里的表單提交
錯誤方案
說起錯誤方案,比如,點擊提交按鈕,本地驗證,驗證通過立即讓按鈕不可點,這些沒問題,而我的錯誤點概括是:在某個最后執(zhí)行的回調(diào)函數(shù)的最后一行,我做了2個操作:1,隱藏Dialog,2,讓提交按鈕可點擊。
這個方案看似沒問題,做到了讓對話框消失,又保證下一次打開Dialog之后,提交按鈕是可點擊的。但它錯誤在于:隱藏Dialog是一個動畫過程,并不是瞬間消失,所以按鈕恢復可點擊之后,Dialog還沒有徹底隱藏,所以只要你點得夠快,就可以多點幾次按鈕。
正確方案
早在打開對話框的時候,將提交按鈕可點擊。做法是在
點擊之后驗證,通過則立即按鈕不可點(this.submitButtonDisabled = true),不通過則不做任何針對按鈕的處理。(這是鐵律,下面會經(jīng)常看到)
驗證通過的話,最后執(zhí)行的某個回調(diào)函數(shù)的最后一行,隱藏對話框。比如this.dialogFormVisible = false,這個變量你也要改成自己用的。
它的核心是2點:早在打開對話框的時候就讓提交按鈕可點擊;驗證通過的話,最后的回調(diào)函數(shù)不應該去管提交按鈕恢復可點擊的事,而是放到下一次打開對話框的時候才讓提交按鈕可點擊。
再說不涉及對話框的提交
不涉及對話框,比如按鈕在頁面上直接存在,又分三種情況:
點擊之后不跳轉(zhuǎn),但按鈕消失
點擊之后不跳轉(zhuǎn),按鈕也不消失
點擊之后跳轉(zhuǎn)頁面
即便是跳轉(zhuǎn)頁面,也是需要時間的,這個期間一樣可以重復提交。不跳轉(zhuǎn)頁面的話,重復提交就更容易發(fā)生了。怎么辦?
情況1:點擊之后不跳轉(zhuǎn),但按鈕消失
這種情況出現(xiàn)在小型提交場合,比如在表格中修改數(shù)據(jù),表格中的某個單元格有一個修改按鈕,點擊之后按鈕消失,只留下數(shù)據(jù)自己,而且,不允許有成功提示框,因為畢竟是小型提交場合,而且提交按鈕消失就已經(jīng)代表了成功。
這就是三種不同的狀態(tài),依次是無數(shù)據(jù)時、編輯狀態(tài)時、有數(shù)據(jù)時
這種情況的處理方案很簡單:
點擊之后驗證,通過則立即不可點,不通過則不針對按鈕處理
服務器返回結(jié)果之后,保存成功則按鈕消失,保存失敗則按鈕依舊存在。無論成功失敗,按鈕都要變成可點擊。由于這里按鈕消失是瞬間發(fā)生,沒有動畫過程,所以就算按鈕變回可點擊,也因為它已經(jīng)消失,因此不會造成重復提交。
這里引出一個問題,就是表格中的小型提交場合,Save按鈕會有一豎列,如何準確給某個按鈕設置不可點擊呢?可以這樣:
從服務器獲取表格數(shù)據(jù)之后要做一步加工,遍歷數(shù)據(jù),加上item.saveButtonDisabled = false之類的語句,然后再賦值給data子對象。
給按鈕綁定方法時,要傳參數(shù),element-ui中可以傳row,也就是@click="clickSave(row)"。
點擊按鈕先驗證數(shù)據(jù),通過則立即row.saveButtonDisabled = true,ajax回調(diào)之后就row.saveButtonDisabled = false,就可以了。
情況2:點擊之后不跳轉(zhuǎn),按鈕也不消失
比如一個表單直接顯示在網(wǎng)頁中,無論提交多少次,頁面都紋絲不動。
這時候再按照上面的情況的處理方案就行不通了,因為比如1秒數(shù)據(jù)就走了一個來回,那么我每1.1秒點擊一次鼠標就可以無限提交下去。
處理方案:
首先,應該避免做這種“無論提交多少次,頁面都紋絲不動”的設定,應該做到ajax返回OK之前,提交按鈕是失效的,OK了就讓提交按鈕可點擊,并且要彈個提示框,這個提示框就可以阻斷連續(xù)提交。這里面還是有一個問題就是,如果在返回OK之后、提示框使用了Dialog,那么彈出的過程中點擊了提交按鈕,依然是可以提交的,因為還是那個動畫問題,提示框彈出是需要時間的。這時候也好辦,別用Dialog,用MessageBox就可以了,它有回調(diào)函數(shù),在回調(diào)函數(shù)里讓提交按鈕可點擊,就行了。
然后,如果有些場景下,必須“頁面紋絲不動”,提示框都不允許有,那么這時候可以采用節(jié)流機制,也就是說按鈕點擊之后3秒內(nèi)就不允許再點擊,即便上一次的提交已經(jīng)1秒完成。方案是:
點擊之后驗證,通過則立即不可點,不通過則不針對按鈕處理
通過之后,設個變量resolve = 0,同時執(zhí)行ajax以及setInterval(fn, 1000),由fn負責判斷:
當ajax返回OK,則resolve += 1
當ajax返回錯誤,則resolve += 2
當延遲3秒,則resolve += 1
當resolve >= 2則讓按鈕可點,且clearInterval
這是一種比較奇葩的算法,也就是說,OK和3秒同時具備的話,resolve為2,則讓按鈕可點,只錯誤的話,resolve會等于或大于2,就立即讓按鈕可點,同時報錯。
如果ajax超時,比如斷網(wǎng)了,那么也會返回錯誤,只不過這個錯誤可能會10秒/20秒/30秒/60秒之后返回(根據(jù)你的ajax配置),其實這也屬于上面說的ajax返回錯誤,所以依然是適用的。
情況3:點擊之后跳轉(zhuǎn)頁面
點擊之后跳轉(zhuǎn)頁面也很常見,無奈跳轉(zhuǎn)頁面也是需要時間的,也可以多次提交。怎么辦?
頁面打開時,讓按鈕可點(跟對話框場景道理一樣)
點擊之后驗證,通過則立即不可點,不通過則不針對按鈕處理
通過之后,當ajax返回OK,則立即跳轉(zhuǎn)(不去恢復成可點),這樣鼠標重復點擊多少次都沒事。當ajax返回錯誤,則彈出錯誤,且按鈕恢復為可點
為什么當ajax返回錯誤后不防范重復點擊?
因為我們將普通用戶定義為:非常喜歡點擊鼠標,但思維正常的人,既然用戶已經(jīng)看到了提示錯誤,當然就不會再重復點擊了,況且錯誤提示往往會是MessageBox,它會阻止重復提交。我們更多的是考慮如何防范鼠標連擊的情況。
惡意重復提交
前端永遠是防君子,難防小人的,惡意攻擊者想要惡意重復提交的話,一定會直接攻擊后端,所以上面所有措施一律無效,還需要后端做措施,這里就不多說了。
最后說說axios攔截提交
根據(jù)網(wǎng)上一些教程,axios攔截提交其實是有問題的:
它的攔截,其實是在重復提交的時候攔截前一次的提交,而我們通常認為,應該攔截后面發(fā)生的所有提交。
ajax速度有時候非???,根本來不及攔截。
api寫的太晦澀了。
需要考慮多種情況,比如有的時候允許3秒提交一次,有的時候隨時可以提交,攔截規(guī)則越搞越復雜。
利用URL和params特征判斷是否能解決問題
比如,規(guī)定時間內(nèi)(比如3秒),或者不設規(guī)定時間,只要向同一個URL發(fā)送同樣的數(shù)據(jù),就禁止發(fā)送。表面上看起來,似乎防范重復提交的本質(zhì)就是要阻止同樣的數(shù)據(jù)重復發(fā)送,但是這里面依然有問題。
比如規(guī)定時間3秒內(nèi)不能發(fā)送同樣數(shù)據(jù),那么,如果是axios全局做判斷,就要考慮,會不會有其他的ajax穿插在3秒里面,所以說,每次準備ajax發(fā)送請求,就要遍歷追溯前三秒發(fā)送過的請求里有沒有重復請求,所以始終要記錄每一次請求,還要記下時間戳,似乎有些麻煩。如果只是根據(jù)每個提交事件做統(tǒng)計,其實道理一樣,也是要遍歷。
而且,如果用戶每隔4秒點擊一次,而ajax返回用時5秒,那么第二次請求就真的會發(fā)出去。
如果不規(guī)定時間,只要發(fā)送同樣數(shù)據(jù)就一定拒絕,那么,如果用戶不經(jīng)意間,在3分鐘內(nèi)2次提交了相同的內(nèi)容,允許不允許提交呢?比如用戶3分鐘中了2次獎,填了2次個人信息,允許提交嗎?按說應該允許,因為有些場合確實可能存在用戶提交同樣內(nèi)容,但是,現(xiàn)在禁止提交,就阻截了正常提交。最后只能是把攔截規(guī)則越搞越復雜。
當然,最為致命的問題是:用戶體驗莫名其妙。無論什么技術,都要把用戶體驗放在第一位,如果開發(fā)者不去管按鈕能否點擊,只做背后的攔截邏輯,也就是始終讓按鈕能點擊,用戶毫無疑問會有很大概率多次點擊,如果趕上ajax慢,用戶會瘋狂點擊,最后瘋掉也不夸張,這不是我們想要的結(jié)果。
所以說前端攔截重復提交的最好辦法一定是用正確邏輯控制按鈕的disabled。
看完了這篇文章,相信你對“element-ui怎么防止重復提交”有了一定的了解,如果想了解更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!