防止表單重複提交

                用戶提交表單時可能因爲網速的原因,或者網頁被惡意刷新,多次點擊submit提交,提交後刷新瀏覽器,瀏覽器URL回車致使表單重複提交,後果可想而知。這種情況我們可以從前端控制,也可以從後端。


                從前端控制的話有多種方式:

1、設置點擊後不可操作時間

 var clickTimeOut = true;
 $(".btn").click(function(e){
 	if(!clickTimeOut)return;
 		setTimeout(function(){clickTimeOut = true;},1000);
 	clickTimeOut = false;
 })

2、當使用ajax時,我們也可以點擊之後禁用該按鈕,complete解開


3、提交後重定向到另一個信息頁面



                從後臺控制:

使用Struts2方式,如下:

1、改變result的type類型爲redirect
         struts2的默認result類型爲dispatcher,當用戶將信息提交到服務器,服務器響應採用forward方式調轉到下一個頁面後,此時地址欄中顯示的是上個頁面的URL,若刷新當前頁面,瀏覽器會將再次提交用戶先前輸入的數據,就會再次出現表單重複提交的問題。如果選擇redirect方式跳轉頁面,這樣就不會出現重複提交的問題;
         缺點:redirect跳轉無法滿足開發過程中的一些需求。

2、採用標籤方式  <s:token />

<form id="login_form" method="post" action="userAction!login">
	<s:token></s:token>
	用 戶<input type="text" name="username" placeholder="輸入用戶" /> 密 碼<input
		type="password" name="password" placeholder="輸入密碼" />
	<div id="btn">
		<a id="loginbutton" href="javascript:void(0)" οnclick="login_submit()">登錄</a>
		<a href="javascript:void(0)" οnclick="login_reset()">清空</a>
	</div>
</form>

<action name="userAction"   class="com.yingjun.sharing.action.UserAction" >
	<interceptor-ref name="myStack" />
        <interceptor-ref name="token" />
        <result name="invalid.token">/WEB-INF/jsp/login.jsp</result>
	<result  name="input">/WEB-INF/jsp/register.jsp</result>
	<result name="regsuccess">/WEB-INF/jsp/login.jsp</result>
</action>

 缺點:對於一次正常提交和一次重複提交,使用token攔截器會使得瀏覽器最終重定向到invalid.token指定的Result


<action name="userAction"   class="com.yingjun.sharing.action.UserAction" >
        <interceptor-ref name="tokenSession" >
              <param name="includeMethods">register</param>
        </interceptor-ref>
        <interceptor-ref name="myStack"/>
	<result  name="input">/WEB-INF/jsp/register.jsp</result>
	<result name="regsuccess">/WEB-INF/jsp/login.jsp</result>
</action>
把token攔截器換爲tokenSession攔截器。tokenSession攔截器與token攔截器唯一的不同是在判斷某個請求爲重複請求之後,並不是立即重定向到名爲invalid.token的Result,而是先阻塞這個重複請求,直到瀏覽器響應最初的正常請求,然後就可以跳轉到處理正常請求後的Result了。

注意:當瀏覽器URL回車的時候,使用tokenSession,又沒有配置<result name="invalid.token">的時候會出現404

該原理就是在頁面加載時,<s: token />產生一個GUID(Globally Unique Identifier,全局唯一標識符)值的隱藏輸入框如:

<input type="hidden" name="struts.token.name" value="struts.token"/>
<input type="hidden" name="struts.token" value="BXPNNDG6BB11ZXHPI4E106CZ5K7VNMHR"/>

同時,將GUID放到會話(session)中;在執行action之前,“token”攔截器將會話token與請求token比較,如果兩者相同,則將會話中的token刪除並往下執行,否則向actionErrors加入錯誤信息。如此一來,如果用戶通過某種手段提交了兩次相同的請求,兩個token就會不同。


知道了原理後我們也可以手工從後臺處理,在session存放一個特殊標識,當表單頁面被請求時,生成一個特殊的字符標誌串,存在session中,同時放在表單的隱藏域裏。接受處理表單數據時,檢查標識字串是否存在,並立即從session中刪除它,然後正常處理數據。如果發現表單提交裏沒有有效的標誌串,這說明表單已經被提交過了,忽略這次提交。


整理自網絡

發佈了260 篇原創文章 · 獲贊 10 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章