Php 点击“后退”按钮后防止表单重新提交

Php 点击“后退”按钮后防止表单重新提交,php,forms,get,refresh,back,Php,Forms,Get,Refresh,Back,我在这里和其他地方搜索了很多帖子,但似乎找不到解决问题的方法。 我有一个显示数据库条目的页面:database.php。可以使用表单筛选这些条目。当我过滤它们并只显示我感兴趣的内容时,我可以单击一个条目(作为链接),它会将我带到该条目页面(通过php GET)。当我在条目页面上(即“view.php?id=1”)并点击后退按钮(返回database.php)时,筛选表单需要确认表单重新提交。有没有办法防止这种情况 以下是一些(简化的)代码示例: Database.php: <form>

我在这里和其他地方搜索了很多帖子,但似乎找不到解决问题的方法。 我有一个显示数据库条目的页面: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...
}
?>
<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while (  ) {
    // display entry
}

?>

1.
2.

我知道有两种方法可以做到这一点。简单的方法和困难的方法

无论采用何种方式,当您处理基于状态的页面(使用
$\u 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");
?>

我希望这有帮助

一件可能有用的事情是让您的筛选表单使用
GET
方法,而不是
POST


浏览器通常会阻止
POST
输入被自动重新提交,而在使用
GET
input时,浏览器不会这样做。此外,这将允许用户使用过滤器链接到您的页面。

我知道这个问题很老,但我自己也有这个问题,我发现有两行代码是有效的:

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

您需要从浏览器历史记录中删除
POST
数据的请求

history.replaceState("", "", "/the/result/page")
见答案


您也可以遵循这种模式。

如果重新加载页面,还可以使用$\u会话检查帖子的原创性。简而言之,检查是否存在唯一或随机字符串

在表单中,使用rand()或microtime()添加具有值集的输入元素:

我使用了在的答案来检测访问是否是由浏览器的后退按钮点击触发的,如果是这样,我使用JavaScript重新加载页面。重新加载页面时,我的代码已经处理了相应的验证,以确保表单不会提交两次。在我的例子中,重要的部分是在单击浏览器的后退按钮后重新访问表单时强制重新加载页面。这是我希望应用此验证的URL中的代码:

<script type="text/javascript">
    if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
        location.reload();
    }
</script>

if(window.performance&&window.performance.navigation.type==window.performance.navigation.type\u BACK\u FORWARD){
location.reload();
}

注意:使用表单中提交的post数据后,应在函数末尾使用这两行。因此,当我们返回重定向页面时,它不会要求您重新提交页面。这就行了。

对我来说,解决方案是

$(document).ready( function() {
//prevent form submit on refresh or resubmit with back button
if ( window.history.replaceState ) window.history.replaceState( null, null, window.location.href );
}

我不理解“简单的方法”。。如果用户在“查看”页面上,则无法重定向他,因为我不知道他想查看该页面上的信息多长时间。我包括了一个重定向按钮,它将用户带回表单页面;这不麻烦。只有当用户按back返回到整个数据库时,问题才会出现。您可以从表单提交到
Database.php
,然后收集所有信息,并在脚本末尾使用
$\u GET
样式的URL在
标题中重定向用户(“地点:http://www.mydomain.com/view.php?databse=this&somethingelse=that');
POST->ServerSide 302 Redirect->Get我知道有很多关于这个主题的帖子。浏览这些帖子我想不出我自己的问题,所以我决定把它作为一个新问题来问。你可能想使用
POST Redirect Get
模式,请参阅,也可能重复此解决方案最适合搜索/筛选表单。对于创建/更新,表单重定向是最好的。我们必须在哪里添加这些行?@user3663我在所有页面上都使用了它,但可能只在接口页面上使用,例如,关于OP的问题,view.php。我在使用session\u cach\u limiter时出错。我也在使用session\u start。当我没有使用session\u cache\u limiter(“private\u no\u expire”)时,它似乎有效;并在包含submit按钮的页面上使用了session_start and header(“缓存控制:无缓存”)。
if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
       $_SESSION['formToken'] = $_POST['formToken'];
      /*continue form processing */
}
<script type="text/javascript">
    if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
        location.reload();
    }
</script>
header("Cache-Control: no cache");

session_cache_limiter("private_no_expire");
$(document).ready( function() {
//prevent form submit on refresh or resubmit with back button
if ( window.history.replaceState ) window.history.replaceState( null, null, window.location.href );
}