場(chǎng)景:在項(xiàng)目開發(fā)中,我們經(jīng)常會(huì)聽到測(cè)試人員抱怨葡盗,我提交表單螟左,表單窗口沒(méi)有及時(shí)關(guān)閉,沒(méi)反應(yīng)觅够,又點(diǎn)擊了一下提交路狮,結(jié)果插入兩條一模一樣的數(shù)據(jù)。其實(shí)蔚约,我們遇到重復(fù)提交的場(chǎng)景大多數(shù)都是這種原因奄妨,今天我們就來(lái)聊一下,如何用最簡(jiǎn)單的方式處理它吧苹祟。
分析原因:如上場(chǎng)景砸抛,可能就是網(wǎng)絡(luò)原因或者其他XXX原因评雌,后臺(tái)數(shù)據(jù)沒(méi)有及時(shí)返回,導(dǎo)致前端頁(yè)面窗口沒(méi)有關(guān)掉直焙。
處理方式1: ?修改頁(yè)面景东,給提交按鈕加個(gè)禁用屬性,亦或者是加個(gè)什么loading的樣式啊奔誓,反正不允許用戶重復(fù)點(diǎn)擊(不推薦)
????具體實(shí)現(xiàn):用戶一點(diǎn)提交斤吐,我就通過(guò)js禁用掉該按鈕不能操作,ajax請(qǐng)求響應(yīng)了厨喂,再把禁用打開和措,用戶(正常用戶,不包括那種直接通過(guò)瀏覽器url來(lái)攻擊你服務(wù)器的用戶)講道理不可能重復(fù)提交蜕煌。呵呵派阱,就是這樣,我后臺(tái)不需要改任何代碼斜纪,分分鐘搞定贫母。我定義為最簡(jiǎn)單的方式,有時(shí)候應(yīng)急這樣做也是可以的嘛盒刚。
優(yōu)點(diǎn):簡(jiǎn)單腺劣,快速,高效因块,應(yīng)急
缺點(diǎn):1橘原,在頁(yè)面上做的這些驗(yàn)證啊,操作啊贮聂,大家懂得靠柑,不安全。
? ? ? ? ? ? 2吓懈,別人太容易攻擊你的網(wǎng)站了歼冰,別人就一直用工具給你重復(fù)提交,不就完了嗎耻警。
處理方式2: 數(shù)據(jù)庫(kù)唯一索引控制(推薦隔嫡,簡(jiǎn)單,可以不用考慮什么分布式啊甘穿,集群啊腮恩,不同用戶并發(fā)操作啊,因?yàn)橹苯釉跀?shù)據(jù)庫(kù)做驗(yàn)證)
具體實(shí)現(xiàn):既然你要插入重復(fù)數(shù)據(jù)温兼,好吧秸滴,我加個(gè)唯一索引,數(shù)據(jù)庫(kù)插入報(bào)錯(cuò)募判,提示 “重復(fù)提交”不就行了嗎荡含。新建一個(gè)字段來(lái)處理咒唆,這個(gè)字段就把它作為唯一索引,UUID或者時(shí)間戳都是可以的释液。那我們可以每次在彈出提交頁(yè)面表單的時(shí)候全释,在后臺(tái)生成一個(gè)唯一索引比如UUID,傳給前端误债,前端提交帶上UUID浸船,我們直接在數(shù)據(jù)庫(kù)保存即可,試想寝蹈,你不刷新頁(yè)面李命,猛點(diǎn)提交按鈕的情況下,每次傳到后臺(tái)的UUID都是同一個(gè)躺盛,直接存數(shù)據(jù)庫(kù)项戴,報(bào)錯(cuò)形帮,提示就完了槽惫。
? ? ? ? 優(yōu)點(diǎn):還是簡(jiǎn)單,快速辩撑,高效界斜,應(yīng)急(不需要引進(jìn)其他任何技術(shù),后臺(tái)代碼也只是加個(gè)try catch而已)
????????缺點(diǎn):1,狂點(diǎn)按鈕合冀,增加數(shù)據(jù)庫(kù)壓力各薇,還有處理方式1的第三個(gè)缺點(diǎn)
? ? ? ? ? ? ? ? ? ? 2,系統(tǒng)中有很多表單提交按鈕君躺,我都需要去加個(gè)莫須有的字段(當(dāng)然峭判,你要是比較勤奮,可以忽略棕叫,但是我覺得這點(diǎn)是比較煩人的林螃,數(shù)據(jù)庫(kù)侵入性高)
? ? ? ? ? ? ? ? ? ? 3,數(shù)據(jù)庫(kù)要是由于各種原因響應(yīng)慢俺泣,用戶確得不到任何提示(當(dāng)然疗认,這點(diǎn)我認(rèn)為不重要)
????????????????????4,通過(guò)數(shù)據(jù)庫(kù)驗(yàn)證伏钠,在性能横漏,速度上都不是最優(yōu)的,比如你連續(xù)點(diǎn)兩次提交熟掂,可能不會(huì)及時(shí)響應(yīng)提示缎浇,但是至少數(shù)據(jù)不會(huì)出問(wèn)題(這個(gè)缺點(diǎn),看項(xiàng)目情況吧赴肚,我覺得還OK)
總結(jié):我個(gè)人不建議使用第一種方式素跺,建議使用第二種方式鹏秋,更建議使用第一種+第二種的組合方式,組合方式有個(gè)好處就是亡笑,用戶不可能出現(xiàn)狂點(diǎn)按鈕的操作侣夷,也就不可能給數(shù)據(jù)庫(kù)造成太大的壓力,綜上仑乌,還是要根據(jù)自己項(xiàng)目的實(shí)際業(yè)務(wù)場(chǎng)景來(lái)做出最優(yōu)選擇百拓。一般用戶量不大,并發(fā)不高的系統(tǒng)晰甚,推薦組合使用衙传。當(dāng)然并發(fā)高,兩種方式我都不建議使用厕九,畢竟第二種是直接操作數(shù)據(jù)庫(kù)蓖捶,壓力大,還可能不能及時(shí)響應(yīng)給用戶扁远。
綜上俊鱼,并發(fā)小,用戶量小畅买,(還要根據(jù)實(shí)際業(yè)務(wù)場(chǎng)景)推薦使用組合方式并闲,因?yàn)楹?jiǎn)單啊,思路簡(jiǎn)單明了谷羞,第二種方式直接操作數(shù)據(jù)庫(kù)帝火,說(shuō)白了就是個(gè)悲觀鎖(當(dāng)然并不是鎖,只是比喻)湃缎,不管你是集群還是分布式犀填,都是OK的,推薦嗓违!
好了九巡,今天簡(jiǎn)單方式解決防重復(fù)提交介紹到這,其實(shí)我覺得一般項(xiàng)目就用組合方式很OK的靠瞎,后期文章還會(huì)介紹其他方式比庄,敬請(qǐng)期待。乏盐。佳窑。