form表單重複提交問題
昨天晚上下班時候在微信上看到一篇表單重複提交的文章,自己實踐了一下,今天跟大家分享一下。
問題的現象:
在一個普通表單頁面,比如下圖1-1我的一個表單頁面(用於向資料庫插入資料)。專案在自己本地執行的時候一般不會出現網路延遲的問題。在當專案釋出到正式伺服器上是就很可能會出現延遲的問題,一般延遲的時候我們就可能會連續提交,導致資料重複提價,資料庫連續插入兩條重複的資料,如圖1-2問題
圖1-1
圖1-2
問題的解決方案:
現在就要防止表單重複提交,那怎麼做才能防止呢。目前有二種方式
一:js方式
(1)對按鈕進行控制
說白了就是在第一次點提交的時候將button設定為disable。
個人感覺:好像這種方式行駛可行的,但目前的一些網頁好像都不是這樣做的,使用者體驗差 (2)做狀態位進行標識... 這個就是設定一個標誌位了來判斷是不是第一次提交。var button = document.getElementById("btn");//獲取button物件 button.attr("disabled","disabled"); window.setTimeout(function(){ $button.removeAttr("disabled");},1000);
<script language="javascript"> var checkSubmitFlg = false; function checkSubmit() { if (!checkSubmitFlg) { checkSubmitFlg = true; return true; } else{ alert("不能重複提交"); return false; } } </script>
個人感覺:這一種也是前端的防止使用者重複提交,但如果同一個頁面可以切換兩個不同表單的時候可能就比價麻煩。而且懂點前端的人稍微弄一下就可以重複提交了
二:伺服器方式
同步令牌方式:伺服器端在處理到達的請求之前,會將請求中包含的令牌值與儲存在當前使用者會話中的令牌值進行比較,看是否匹配。在處理完該請求後,且在答覆傳送給客戶端之前,將會產生一個新的令牌,該令牌除傳給客戶端以外,也會將使用者會話中儲存的舊的令牌進行替換。這樣如果使用者回退到剛才的提交頁面並再次提交的話,客戶端傳過來的令牌就和伺服器端的令牌不一致,從而有效地防止了重複提交的發生。
這一塊我當時看的時候搞不懂為什麼可以控制表單重複提交,其實它就是在到達表單頁面的時候產生了一個token令牌,這個令牌放在session裡面,同時放到表單的隱藏域裡面,當表單第一次提交時,去後臺判斷是否跟session的一樣,一樣就進行insert操作,同時產生新的token令牌,同時更新session的令牌資料,這時如果表單重複提交了,表單的令牌資訊還是老的,session裡面已經更新了,所以不一樣了。
令牌,struts2,springmvc好像都有實現方式,都比較簡單,大家可以去試試
struts2的token令牌實現可看點選開啟連結