2011-01-06 120 views
12

如何防止多次點擊多個表單提交的PHP如何防止多次點擊多個表單提交的PHP

+2

禁用提交按鈕! – 2011-01-06 10:45:21

+1

由於問題是關於服務器端行爲(PHP),我建議看看下面的問題:http://stackoverflow.com/questions/218907/how-to-handle-multiple-submissions-server-side – Kel 2011-01-06 10:49:23

+4

`` – karim79 2011-01-06 10:50:35

回答

5

你可以(使用JavaScript)首次點擊後,關閉按鈕,也對後面的檢查(只是在他們禁用JavaScript的情況下),檢查它們是否剛剛提交。

對後端進行檢查的方式有很多種。一種方法是在第一次點擊會話變量時設置會話變量,這可以讓系統知道它正在處理中。如果他們點擊第二次,第三次或第四次,那麼它只能檢查會話變量,如果它表明它已被點擊,則不會處理。

這只是一個例子 - 你可以用它作爲開始。

30

使用每次顯示錶單時只能使用一次的唯一標記;防止CSRFreplay攻擊也是有用的。 一個小例子:

<?php 
session_start(); 

/** 
* Creates a token usable in a form 
* @return string 
*/ 
function getToken(){ 
    $token = sha1(mt_rand()); 
    if(!isset($_SESSION['tokens'])){ 
    $_SESSION['tokens'] = array($token => 1); 
    } 
    else{ 
    $_SESSION['tokens'][$token] = 1; 
    } 
    return $token; 
} 

/** 
* Check if a token is valid. Removes it from the valid tokens list 
* @param string $token The token 
* @return bool 
*/ 
function isTokenValid($token){ 
    if(!empty($_SESSION['tokens'][$token])){ 
    unset($_SESSION['tokens'][$token]); 
    return true; 
    } 
    return false; 
} 

// Check if a form has been sent 
$postedToken = filter_input(INPUT_POST, 'token'); 
if(!empty($postedToken)){ 
    if(isTokenValid($postedToken)){ 
    // Process form 
    } 
    else{ 
    // Do something about the error 
    } 
} 

// Get a token for the form we're displaying 
$token = getToken(); 
?> 
<form method="post"> 
    <fieldset> 
    <input type="hidden" name="token" value="<?php echo $token;?>"/> 
    <!-- Add form content --> 
    </fieldset> 
</form> 

一個重定向結合起來,所以你保持完美的前後行爲。 有關重定向的更多信息,請參閱POST/redirect/GET模式。

1

您可以添加這樣的事情

<input type="hidden" name="form-token" value="someRandomNumber">

然後在後端,你必須識別多個表單提交的保存方式。當然,這個解決方案有一些包袱,因爲你必須刪除你知道已經完成處理的表單標記等。

在大多數情況下,禁用的表單可以做到這一點,例如通過禁用按鈕或通過添加return false到表單提交事件(不知道這是否工作沒有jQuery雖然)。

1

我建議不要禁用提交按鈕,因爲如果出現臨時性網絡問題(即請求根本沒有經過),如果用戶選擇中止提交(Esc鍵/停止按鈕),他不能在網絡服務恢復後再次提交,而不得不重新加載頁面並再次填寫全部表單條目。

0

這是最黎民回答您的問題

0

可你只是隱藏點擊按鈕?它不會影響表單處理(因爲我知道問題是立即禁用按鈕),但它基本上會做同樣的事情。如果你真的擔心它,你甚至可以只顯示另一個實際上沒有做任何事情的按鈕。可能是一種非常規的解決方法,但是還是一種解決方法。