這種問題出現(xiàn)的原因或者說應(yīng)用場景大致如下:
- 網(wǎng)絡(luò)延遲肪虎,服務(wù)器未能及時做出響應(yīng),導(dǎo)致用戶不斷重復(fù)點擊提交按鈕
- 用戶雙擊有意識的雙擊或者多次點擊提交按鈕
- F5刷新頁面
- 點擊瀏覽器后退按鈕
解決方案主要分為客戶端(瀏覽器)和服務(wù)端以及數(shù)據(jù)庫惧蛹。
js禁止按鈕點擊
這種方式是一種比較簡單也比較常用的方法扇救。當(dāng)用戶提交完表單后刑枝,用javascript禁用提交按鈕讓按鈕不可點擊。也就是設(shè)置disabled屬性為disabled或者true即可迅腔。按鈕倒計時
頁面上表單提交后装畅,將按鈕置灰不可點擊后加入倒計時,比如5秒或者10秒后按鈕恢復(fù)點擊狀態(tài)才能再次提交沧烈。這種方式也可以避免大量請求掠兄,減輕服務(wù)端訪問的壓力。驗證碼
頁面上添加驗證碼掺出,不管驗證輸入正確與否徽千,提交后均刷新驗證碼。ajax加鎖
采用ajax方式提交表單時汤锨,設(shè)置一個布爾變量(true/false),當(dāng)然其他類型變量也可以百框。初始時為true可以提交,在前端向服務(wù)器發(fā)出請求后闲礼,服務(wù)端響應(yīng)結(jié)果沒有回來之前將該值置為false,正常響應(yīng)時再置為true铐维。提交后重定向到一個提交成功的頁面
表單提交后跳轉(zhuǎn)到另外一個成功頁面柬泽。這樣可以避免用戶按F5導(dǎo)致的重復(fù)提交,瀏覽器也不會出現(xiàn)表單重復(fù)提交的警告嫁蛇,以及消除按瀏覽器前進(jìn)和后退按導(dǎo)致的同樣問題锨并。服務(wù)端生成一個唯一的token
首先在服務(wù)端生成一個token保證唯一性,然后將這個token保存在session或者redis等緩存中睬棚。與此同時將token放到頁面的隱藏input中第煮,發(fā)給瀏覽器。用戶在頁面上提交時帶著這個token一塊提交到服務(wù)端抑党,服務(wù)端通過比對token的值包警。如果相等代表首次提交,此時將session或者緩存中保存的token值remove掉底靠,反之則認(rèn)為重復(fù)提交害晦,服務(wù)端不予處理。cookie記錄表單提交的狀態(tài)
使用Cookie記錄表單提交的狀態(tài)暑中,根據(jù)其狀態(tài)可以檢查是否已經(jīng)提交過表單壹瘟。跟上一種類似,服務(wù)端生成token存入Cookie鳄逾,表單提交時將Cookie中token和服務(wù)端token比對數(shù)據(jù)庫添加唯一索引約束
向數(shù)據(jù)庫字段添加一個唯一索引稻轨。如果表單重復(fù)提交,那么數(shù)據(jù)庫插入重復(fù)記錄時严衬,唯一約束能有效避免重復(fù)入庫澄者。這樣控制的話笆呆,日志會出現(xiàn)Your program attempts to store duplicate values in a database column that is constrained by a unique index的報錯信息,看著有點不爽粱挡。