php 防止在点击返回按钮时重新提交表单
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15226744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prevent Form resubmission upon hitting back button
提问by user1889382
I have searched many posts here and elsewhere but can't seem to find a solution to my problem. I have a page which displays database entries: database.php. These entries can be filtered with a form. When I filter them and only display the ones I am interested in I can click an entry (as a link) which takes me to that entries page (via php GET). When I am on that entries page (i.e., "view.php?id=1") and hit the back button (back to database.php), the filter form requires to confirm the form resubmission. Is there any way to prevent this?
我在这里和其他地方搜索了许多帖子,但似乎找不到解决我的问题的方法。我有一个显示数据库条目的页面:database.php。可以使用表单过滤这些条目。当我过滤它们并只显示我感兴趣的那些时,我可以单击一个条目(作为链接),它将我带到该条目页面(通过 php GET)。当我在那个条目页面(即“view.php?id=1”)并点击后退按钮(返回到database.php)时,过滤器表单需要确认表单重新提交。有什么办法可以防止这种情况吗?
here are some (simplified) code examples:
下面是一些(简化的)代码示例:
Database.php:
数据库.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...
}
?>
Now as mentioned, if I click on the link, it takes me to "view.php?id=whatever". On that page, I just get the ID from the url to display that single entry:
现在如前所述,如果我点击链接,它会带我到“view.php?id=whatever”。在该页面上,我只是从 url 获取 ID 以显示该单个条目:
view.php:
视图.php:
<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while ( ) {
// display entry
}
?>
If I now hit the back button, the form on database.php (the one used to filter the DB results) requires confirmation for resubmission. Not only is this very annoying, its also useless to me.
如果我现在点击后退按钮,database.php 上的表单(用于过滤数据库结果的表单)需要确认重新提交。这不仅很烦人,而且对我也没用。
How can I fix this? I hope the code examples and explanation of my problem are sufficient. If not let me know and I'll try to specify.
我怎样才能解决这个问题?我希望我的问题的代码示例和解释足够了。如果没有让我知道,我会尽量指定。
回答by Ryan Konkolewski
I know this question is old, but having this issue myself, two lines I've discovered that works are:
我知道这个问题很老,但我自己也有这个问题,我发现有两行是有效的:
header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
回答by Phillip Berger
There are two ways I know of to do this. The simple way and the hard way.
我知道有两种方法可以做到这一点。简单的方法和困难的方法。
Regardless of the way, when you are dealing with a state-based page (using $_SESSION), which you should be doing to keep your pages "live" and under your control, is prevent the caching of all pages like this:
无论哪种方式,当您处理基于状态的页面(使用$_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");
?>
The hard way involves generating an id and storing it somewhere on the page as a hidden input or a &_SESSIONcookie. Then you store the same id on the server as a $_SESSION. If they don't match, a series of preprogrammed ifelsetype statements cause nothing to happen with the page is resubmitted (which is what it tries to do when you click back).
困难的方法是生成一个 id 并将其作为隐藏输入或&_SESSIONcookie存储在页面上的某个位置。然后你在服务器上存储相同的 id 作为$_SESSION. 如果它们不匹配,ifelse则重新提交页面时一系列预编程的类型语句不会导致任何事情发生(这是它在您单击返回时尝试执行的操作)。
The easy way is to simply redirect the user back to the form submission page if the form was submitted successfully, like so:
如果表单提交成功,简单的方法是简单地将用户重定向回表单提交页面,如下所示:
header('Location: http://www.mydomain.com/redirect.php');
I hope this helps!
我希望这有帮助!
回答by tanios
One thing that might help is making your filter form use a GETmethod instead of POST.
可能有帮助的一件事是让您的过滤器表单使用GET方法而不是POST.
Browsers usually prevent POSTinput from being automatically resubmitted, which is something they don't do when GETinput is used. Also, this will let users link to your page using a filter.
浏览器通常会阻止POST自动重新提交输入,这GET是使用输入时他们不会做的事情。此外,这将让用户使用过滤器链接到您的页面。
回答by Jaime Montoya
I used the answer at How do I detect if a user has got to a page using the back button?to detect whether or not the visit was triggered by a browser's back button click, and then if that was the case, I used JavaScript to reload the page. When the page is reloaded, my code already handles the corresponding validations to make sure that the form is never submitted twice. The important part in my case was forcing the page reload when the form was revisited after clicking the browser's back button. This is my code in the URL where I wanted to apply this validation:
我使用了如何检测用户是否使用后退按钮进入页面?检测访问是否由浏览器的后退按钮点击触发,如果是这种情况,我使用 JavaScript 重新加载页面。当页面重新加载时,我的代码已经处理了相应的验证,以确保表单永远不会提交两次。在我的案例中,重要的部分是在单击浏览器的后退按钮后重新访问表单时强制重新加载页面。这是我要应用此验证的 URL 中的代码:
<script type="text/javascript">
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
location.reload();
}
</script>
回答by Hemanth Paidiparthi
header("Cache-Control: no cache");
header("缓存控制:无缓存");
session_cache_limiter("private_no_expire");
session_cache_limiter("private_no_expire");
NOTE : After using the post data what you have submitted from form then,these two lines should be used at the end of function.so, when we are back to the redirected page ,it will not ask you to resubmit the page . This will work.
注意:在使用了你从表单提交的post数据之后,这两行应该用在function的末尾。所以,当我们回到重定向的页面时,它不会要求你重新提交页面。这将起作用。
回答by SilentStone
An alternative solution that also works if/when the page is reloaded involves checking the post's originality using $_SESSION. In a nutshell, check for a unique or random string.
如果/当页面重新加载时,另一种解决方案也适用,包括使用 $_SESSION 检查帖子的原创性。简而言之,检查唯一或随机字符串。
In the form, add an input element with a value set using rand() or microtime():
在表单中,添加一个使用 rand() 或 microtime() 设置的值的输入元素:
<input type="hidden" name="formToken" value="<?php echo microtime();?>"/>
And then wrap the PHP function to validate and parse the form data in an if block:
然后在 if 块中包装 PHP 函数以验证和解析表单数据:
if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
$_SESSION['formToken'] = $_POST['formToken'];
/*continue form processing */
}
回答by Eugen Konkov
You need to remove the request which POSTdata from browser history
您需要POST从浏览器历史记录中删除请求哪些数据
history.replaceState("", "", "/the/result/page")
See thisanswer
看到这个答案
Also you may follow the Post/Redirect/Getpattern.
你也可以遵循这个Post/Redirect/Get模式。

