2013-03-05 195 views
17

我已經在這裏和其他地方搜索了很多帖子,但似乎無法找到解決我的問題。 我有一個顯示數據庫條目的頁面:database.php。這些條目可以用表單過濾。當我過濾它們,只顯示我感興趣的,我可以點擊一個條目(作爲一個鏈接),帶我到該條目頁(通過PHP GET)。當我在該條目頁面(即「view.php?id = 1」)並點擊後退按鈕(返回到database.php)時,過濾器表單需要確認表單重新提交。有什麼辦法可以防止這種情況發生?防止表單重新提交後點擊按鈕

這裏有一些(簡化)代碼示例:

database.php中:

<form> 
    <select> 
     <option>1</option> 
     <option>2 
     <option> 
    </select> 
    <input type="submit" name="apply_filter" /> 
</form> 
<?php 
if (isset($_POST[ "apply_filter" ])) { // display filtered entries 
    $filter = $_POST[ "filter" ]; 
    $q = "Select * from table where col = '" . $filter . "'"; 
    $r = mysql_query($q); 
} else { // display all entries 
    $q = "Select * from table"; 
    $r = mysql_query($q); 
} 
while ($rec = mysql_fetch_assoc($r)) { 
    echo "<a href='view.php?id=" . $rec[ "id" ] . "'>" . $rec[ "name" ] . "</a><br />"; // this is where the link to the view.php page is... 
} 
?> 

現在提到,如果我點擊鏈接,就帶我到「view.php? ID =什麼」。在該頁面中,我剛剛從URL獲得ID,以顯示單個條目:

view.php:

<?php 
$id = $_GET[ "id" ]; 
$q = "Select * from table where id = '" . $id . "'"; 
$r = mysql_query($q); 
while () { 
    // display entry 
} 

?> 

如果我現在打的返回按鈕,在database.php中的形式(用於過濾DB結果的那個)需要確認重新提交。這不僅非常煩人,對我也無用。

我該如何解決這個問題?我希望代碼示例和我的問題的解釋是足夠的。如果不讓我知道,我會嘗試指定。

+3

** POST ** - > * ServerSide 302重定向* - > ** GET ** – scunliffe 2013-03-05 15:15:09

+0

我知道有很多這個主題的帖子。瀏覽他們我無法弄清楚我自己的問題,所以我決定把它作爲一個新問題。 – user1889382 2013-03-05 15:16:19

+0

您可能想要使用'Post-Redirect-Get'模式,請參閱https://en.wikipedia.org/wiki/Post/Redirect/Get以及http://stackoverflow.com/questions/15288229/automatically-在瀏覽器中重新發送請求時使用後退按鈕 – 2014-07-29 14:59:31

回答

9

我知道有兩種方法可以做到這一點。簡單的方式和艱難的方式。

無論如何,當您處理基於狀態的頁面(使用$_SESSION)時,您應該採取哪些措施來保持頁面「實時」並在您的控制之下,從而防止像這樣緩存所有頁面:

<?php 
//Set no caching 
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false); 
header("Pragma: no-cache"); 
?> 

難的方法包括生成一個ID,並在頁面上的某個地方把它作爲一個隱藏的輸入或&_SESSION餅乾。然後你在服務器上存儲相同的標識爲$_SESSION。如果它們不匹配,則一系列預編程的ifelse類型語句會在頁面重新提交時發生任何事情(這是您在單擊時嘗試執行的操作)。

最簡單的方法是簡單地將用戶重定向回表單提交頁面,如果表單已成功提交,就像這樣:

header('Location: http://www.mydomain.com/redirect.php'); 

我希望這有助於!

+1

我不理解「簡單的方法」..如果用戶在「查看」頁面上沒有辦法重定向他,因爲我不知道他多久,他想要查看該頁面上的信息。我包含一個重定向按鈕,它將用戶帶回到表單頁面;這並不麻煩。只有當用戶按下回到整個數據庫時,問題纔會出現。 – user1889382 2013-03-05 15:10:13

+0

你會從你的表單提交到'Database.php',然後收集所有的信息,並在該腳本的末尾使用'header_'中的$ _GET'樣式URL重定向用戶('Location:http:// www.mydomain.com/view.php?databse=this&somethingelse=that');' – 2013-03-05 15:15:32

3

有一件事可能會幫助您的過濾器窗體使用GET方法而不是POST

瀏覽器通常會阻止POST輸入被自動重新提交,這是使用GET輸入時不會執行的操作。此外,這將讓用戶使用過濾器鏈接到您的頁面。

+1

該解決方案最適合搜索/過濾表單。對於創建/更新表單重定向是最好的。 – 2015-09-02 10:14:32

17

我知道這個問題是舊的,但有這個問題我自己,兩行我發現作品有:

header("Cache-Control: no cache"); 
session_cache_limiter("private_no_expire"); 
+0

我們必須添加這些行嗎? – user3663 2017-09-25 07:58:35

+0

@ user3663我在所有頁面上都使用了它,但可能僅在界面頁面上工作,例如view.php關於OP的問題。 – 2017-09-25 12:52:35

-1

您需要刪除請求從瀏覽器的歷史POST數據

history.replaceState("", "", "/the/result/page") 

this答案

您也可以按照Post/Redirect/Get模式。

0

如果/當頁面被重新加載時,另一種解決方案也可以使用,它涉及使用$ _SESSION檢查帖子的原創性。簡而言之,檢查一個唯一的或隨機的字符串。在if塊

<input type="hidden" name="formToken" value="<?php echo microtime();?>"/> 

然後包裹PHP函數來驗證並解析形式的數據:

在表單中,使用RAND()或microtime中()中設置的值增加一個輸入元件:

if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){ 
     $_SESSION['formToken'] = $_POST['formToken']; 
     /*continue form processing */ 
} 
相關問題