防止web頁面表單重復提交的方法有哪些?
1.js方法解決:關于js方法解決就是說通過js動態控制提交按鈕不能多次點擊,或者多次點擊不起作用。
方案一:通過設立標識使表單不能重復提交:
var flag=true; function Sub(){ if(flag){flag = false;document.form1.onsubmit();}}
方案二:一次點擊后使得提交按鈕變成不可用
<input type="button" value="login" onclick="this.disabled=true;this.form.submit();" />
總的來說,js解決方案是基本可以防止重復點擊提交按鈕造成的重復提交問題,但是前進后退操作,或者F5刷新頁面等問題并不能得到解決。
最重要的一點,前端的代碼只能防止不懂js的用戶,如果碰到懂得js的編程人員,那js方法就沒用了。
2.設置HTTP報頭,控制表單緩存,使得所控制的表單不緩存信息,這樣用戶就無法通過重復點擊按鈕去重復提交表單。
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
但是這樣做也有局限性,用戶在提交頁面點擊刷新也會造成表單的重復提交。
3.通過PRG設計模式(用來防止F5刷新重復提交表單):
PRG模式通過響應頁面Header返回HTTP狀態碼進行頁面跳轉替代響應頁面跳轉過程。具體過程如下:
客戶端用POST方法請求服務器端數據變更,服務器對客戶端發來的請求進行處理重定向到另一個結果頁面上,客戶端所有對頁面的顯示請求都用get方法告知服務器端,這樣做,后退再前進或刷新的行為都發出的是get請求,不會對server產生任何數據更改的影響。
但此方法也不能防止所有情況:例如用戶多次點擊提交按鈕;惡意用戶避開客戶端預防多次提交手段,進行重復提交請求;
以上都說的是在客戶端如何防止表單重復提交,下面說一下服務器端有哪些可行的方法。
4.如果是注冊或存入數據庫的操作,可以通過在數據庫中字段設立唯一標識來解決,這樣在進行數據庫插入操作時,因為每次插入的數據都相同,數據庫會拒絕寫入。這樣也避免了向數據庫中寫入垃圾數據的情況,同時也解決了表單重復提交問題。
但是這種方法在業務邏輯上感覺是說不過去的,本來該有的邏輯,缺因為數據庫該有的設計隱藏了。而且這種方法也有一定的功能局限性,只適用于某系特定的插入操作。
5.session方法:
在struts框架中防止表單重復提交的方法是生成Token存入session,以此判斷表單是否是第一次提交。以下給大家解釋一下運行流程。
首先客戶端請求服務器中的表單,服務器將客戶機所請求的表單發給客戶機同時發送一個特殊的隨機數(Token)作為表單號存在表單的隱藏域中(type=hidden),并且存入服務器端的session中。在客戶端填寫完表單內容向服務器提交時,同時也將隱藏域中的表單號發給服務器端,服務器端此時會檢測服務器端的表單號是否存在,如果存在,則進行提交操作,并刪除此表單號,否則,服務器視為客戶機端重復提交表單,不予操作。
此處貼出生成Token的代碼(保證隨機數的獨一無二性):
class Token{ private Token(){} private static Token instance = new Token();public Token getInstance(){ return instance;}//隨機數發生器public String getToken(){String token = System.currentTimeMillis() + "" + new Random().nextInt();//獲得毫秒數加隨機數try {MessageDigest md = MessageDigest.getInstance("md5"); byte[] md5 = md.digest(token.getBytes());BASE64Encoder base = new BASE64Encoder();base.encode(md5);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}}
要強調的是,利用session方法解決表單重復問題是十分完美的,基本上可以應對各種重復提交問題。
但!是不是之前在客戶端防止表單重復提交的種種方法就不使用了呢?
答案是否定的,我們需要多種方法混合使用才能達到最好的效果,也許有人會問,不是說session方法基本可以應對各種重復提交問題了嗎?
這里我們所說的達到最好效果指的是,給用戶更好地體驗,例如用戶點擊了提交按鈕,這時將按鈕變為不可用的,用以告訴用戶你已經提交內容了,不可重復提交。還有如果無論什么情況都用session防止表單重復提交問題,反而無形的增加了服務器端的負擔。