溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

element-ui怎么防止重復(fù)提交

發(fā)布時間:2021-02-02 10:52:04 來源:億速云 閱讀:422 作者:小新 欄目:web開發(fā)

小編給大家分享一下element-ui怎么防止重復(fù)提交,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

先說對話框(Dialog)里的表單提交

錯誤方案

說起錯誤方案,比如,點擊提交按鈕,本地驗證,驗證通過立即讓按鈕不可點,這些沒問題,而我的錯誤點概括是:在某個最后執(zhí)行的回調(diào)函數(shù)的最后一行,我做了2個操作:1,隱藏Dialog,2,讓提交按鈕可點擊。

這個方案看似沒問題,做到了讓對話框消失,又保證下一次打開Dialog之后,提交按鈕是可點擊的。但它錯誤在于:隱藏Dialog是一個動畫過程,并不是瞬間消失,所以按鈕恢復(fù)可點擊之后,Dialog還沒有徹底隱藏,所以只要你點得夠快,就可以多點幾次按鈕。

正確方案

  1. 早在打開對話框的時候,將提交按鈕可點擊。做法是在<el-dialog>上加入open事件函數(shù):@open="submitButtonDisabled = false",其中submitButtonDisabled是我控制提交按鈕的變量,你可以改成你自己用的。

  2. 點擊之后驗證,通過則立即按鈕不可點(this.submitButtonDisabled = true),不通過則不做任何針對按鈕的處理。(這是鐵律,下面會經(jīng)??吹剑?/p>

  3. 驗證通過的話,最后執(zhí)行的某個回調(diào)函數(shù)的最后一行,隱藏對話框。比如this.dialogFormVisible = false,這個變量你也要改成自己用的。

它的核心是2點:早在打開對話框的時候就讓提交按鈕可點擊;驗證通過的話,最后的回調(diào)函數(shù)不應(yīng)該去管提交按鈕恢復(fù)可點擊的事,而是放到下一次打開對話框的時候才讓提交按鈕可點擊。

再說不涉及對話框的提交

不涉及對話框,比如按鈕在頁面上直接存在,又分三種情況:

  1. 點擊之后不跳轉(zhuǎn),但按鈕消失

  2. 點擊之后不跳轉(zhuǎn),按鈕也不消失

  3. 點擊之后跳轉(zhuǎn)頁面

即便是跳轉(zhuǎn)頁面,也是需要時間的,這個期間一樣可以重復(fù)提交。不跳轉(zhuǎn)頁面的話,重復(fù)提交就更容易發(fā)生了。怎么辦?

情況1:點擊之后不跳轉(zhuǎn),但按鈕消失

這種情況出現(xiàn)在小型提交場合,比如在表格中修改數(shù)據(jù),表格中的某個單元格有一個修改按鈕,點擊之后按鈕消失,只留下數(shù)據(jù)自己,而且,不允許有成功提示框,因為畢竟是小型提交場合,而且提交按鈕消失就已經(jīng)代表了成功。

element-ui怎么防止重復(fù)提交

這就是三種不同的狀態(tài),依次是無數(shù)據(jù)時、編輯狀態(tài)時、有數(shù)據(jù)時

這種情況的處理方案很簡單:

  1. 點擊之后驗證,通過則立即不可點,不通過則不針對按鈕處理

  2. 服務(wù)器返回結(jié)果之后,保存成功則按鈕消失,保存失敗則按鈕依舊存在。無論成功失敗,按鈕都要變成可點擊。由于這里按鈕消失是瞬間發(fā)生,沒有動畫過程,所以就算按鈕變回可點擊,也因為它已經(jīng)消失,因此不會造成重復(fù)提交。

這里引出一個問題,就是表格中的小型提交場合,Save按鈕會有一豎列,如何準(zhǔn)確給某個按鈕設(shè)置不可點擊呢?可以這樣:

  1. 從服務(wù)器獲取表格數(shù)據(jù)之后要做一步加工,遍歷數(shù)據(jù),加上item.saveButtonDisabled = false之類的語句,然后再賦值給data子對象。

  2. 給按鈕綁定方法時,要傳參數(shù),element-ui中可以傳row,也就是@click="clickSave(row)"。

  3. 點擊按鈕先驗證數(shù)據(jù),通過則立即row.saveButtonDisabled = true,ajax回調(diào)之后就row.saveButtonDisabled = false,就可以了。

情況2:點擊之后不跳轉(zhuǎn),按鈕也不消失

比如一個表單直接顯示在網(wǎng)頁中,無論提交多少次,頁面都紋絲不動。

這時候再按照上面的情況的處理方案就行不通了,因為比如1秒數(shù)據(jù)就走了一個來回,那么我每1.1秒點擊一次鼠標(biāo)就可以無限提交下去。

處理方案:

首先,應(yīng)該避免做這種“無論提交多少次,頁面都紋絲不動”的設(shè)定,應(yīng)該做到ajax返回OK之前,提交按鈕是失效的,OK了就讓提交按鈕可點擊,并且要彈個提示框,這個提示框就可以阻斷連續(xù)提交。這里面還是有一個問題就是,如果在返回OK之后、提示框使用了Dialog,那么彈出的過程中點擊了提交按鈕,依然是可以提交的,因為還是那個動畫問題,提示框彈出是需要時間的。這時候也好辦,別用Dialog,用MessageBox就可以了,它有回調(diào)函數(shù),在回調(diào)函數(shù)里讓提交按鈕可點擊,就行了。

然后,如果有些場景下,必須“頁面紋絲不動”,提示框都不允許有,那么這時候可以采用節(jié)流機(jī)制,也就是說按鈕點擊之后3秒內(nèi)就不允許再點擊,即便上一次的提交已經(jīng)1秒完成。方案是:

點擊之后驗證,通過則立即不可點,不通過則不針對按鈕處理

通過之后,設(shè)個變量resolve = 0,同時執(zhí)行ajax以及setInterval(fn, 1000),由fn負(fù)責(zé)判斷:

  1. 當(dāng)ajax返回OK,則resolve += 1

  2. 當(dāng)ajax返回錯誤,則resolve += 2

  3. 當(dāng)延遲3秒,則resolve += 1

  4. 當(dāng)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)頁面也是需要時間的,也可以多次提交。怎么辦?

  1. 頁面打開時,讓按鈕可點(跟對話框場景道理一樣)

  2. 點擊之后驗證,通過則立即不可點,不通過則不針對按鈕處理

  3. 通過之后,當(dāng)ajax返回OK,則立即跳轉(zhuǎn)(不去恢復(fù)成可點),這樣鼠標(biāo)重復(fù)點擊多少次都沒事。當(dāng)ajax返回錯誤,則彈出錯誤,且按鈕恢復(fù)為可點

為什么當(dāng)ajax返回錯誤后不防范重復(fù)點擊?

因為我們將普通用戶定義為:非常喜歡點擊鼠標(biāo),但思維正常的人,既然用戶已經(jīng)看到了提示錯誤,當(dāng)然就不會再重復(fù)點擊了,況且錯誤提示往往會是MessageBox,它會阻止重復(fù)提交。我們更多的是考慮如何防范鼠標(biāo)連擊的情況。

惡意重復(fù)提交

前端永遠(yuǎn)是防君子,難防小人的,惡意攻擊者想要惡意重復(fù)提交的話,一定會直接攻擊后端,所以上面所有措施一律無效,還需要后端做措施,這里就不多說了。

最后說說axios攔截提交

根據(jù)網(wǎng)上一些教程,axios攔截提交其實是有問題的:

  • 它的攔截,其實是在重復(fù)提交的時候攔截前一次的提交,而我們通常認(rèn)為,應(yīng)該攔截后面發(fā)生的所有提交。

  • ajax速度有時候非常快,根本來不及攔截。

  • api寫的太晦澀了。

  • 需要考慮多種情況,比如有的時候允許3秒提交一次,有的時候隨時可以提交,攔截規(guī)則越搞越復(fù)雜。

利用URL和params特征判斷是否能解決問題

比如,規(guī)定時間內(nèi)(比如3秒),或者不設(shè)規(guī)定時間,只要向同一個URL發(fā)送同樣的數(shù)據(jù),就禁止發(fā)送。表面上看起來,似乎防范重復(fù)提交的本質(zhì)就是要阻止同樣的數(shù)據(jù)重復(fù)發(fā)送,但是這里面依然有問題。

比如規(guī)定時間3秒內(nèi)不能發(fā)送同樣數(shù)據(jù),那么,如果是axios全局做判斷,就要考慮,會不會有其他的ajax穿插在3秒里面,所以說,每次準(zhǔn)備ajax發(fā)送請求,就要遍歷追溯前三秒發(fā)送過的請求里有沒有重復(fù)請求,所以始終要記錄每一次請求,還要記下時間戳,似乎有些麻煩。如果只是根據(jù)每個提交事件做統(tǒng)計,其實道理一樣,也是要遍歷。

而且,如果用戶每隔4秒點擊一次,而ajax返回用時5秒,那么第二次請求就真的會發(fā)出去。

如果不規(guī)定時間,只要發(fā)送同樣數(shù)據(jù)就一定拒絕,那么,如果用戶不經(jīng)意間,在3分鐘內(nèi)2次提交了相同的內(nèi)容,允許不允許提交呢?比如用戶3分鐘中了2次獎,填了2次個人信息,允許提交嗎?按說應(yīng)該允許,因為有些場合確實可能存在用戶提交同樣內(nèi)容,但是,現(xiàn)在禁止提交,就阻截了正常提交。最后只能是把攔截規(guī)則越搞越復(fù)雜。

當(dāng)然,最為致命的問題是:用戶體驗?zāi)涿?。無論什么技術(shù),都要把用戶體驗放在第一位,如果開發(fā)者不去管按鈕能否點擊,只做背后的攔截邏輯,也就是始終讓按鈕能點擊,用戶毫無疑問會有很大概率多次點擊,如果趕上ajax慢,用戶會瘋狂點擊,最后瘋掉也不夸張,這不是我們想要的結(jié)果。

所以說前端攔截重復(fù)提交的最好辦法一定是用正確邏輯控制按鈕的disabled。

看完了這篇文章,相信你對“element-ui怎么防止重復(fù)提交”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI