php 页面刷新时如何防止表单重新提交 (F5 / CTRL+R)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6320113/
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
How to prevent form resubmission when page is refreshed (F5 / CTRL+R)
提问by user701510
I have a simple form that submits text to my SQL table. The problem is that after the user submits the text, they can refresh the page and the data gets submitted again without filling the form again. I could redirect the user to another page after the text is submitted, but I want users to stay on the same page.
我有一个向我的 SQL 表提交文本的简单表单。问题是用户提交文本后,他们可以刷新页面,数据再次提交,而无需再次填写表单。我可以在提交文本后将用户重定向到另一个页面,但我希望用户停留在同一页面上。
I remember reading something about giving each user a unique session id and comparing it with another value which solved the problem I am having but I forgot where it is.
我记得读过一些关于为每个用户提供唯一会话 ID 并将其与解决我遇到的问题的另一个值进行比较的内容,但我忘记了它在哪里。
采纳答案by Keverw
Use the Post/Redirect/Get pattern. http://en.wikipedia.org/wiki/Post/Redirect/Get
使用发布/重定向/获取模式。http://en.wikipedia.org/wiki/Post/Redirect/Get
With my website, I will store a message in a cookie or session, redirect after the post, read the cookie/session, and then clear the value of that session or cookie variable.
对于我的网站,我会将消息存储在 cookie 或会话中,在发布后重定向,读取 cookie/会话,然后清除该会话或 cookie 变量的值。
回答by dtbaker
I would also like to point out that you can use a javascript approach, window.history.replaceState
to prevent a resubmit on refresh and back button.
我还想指出,您可以使用 javascript 方法window.history.replaceState
来防止在刷新和后退按钮时重新提交。
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
Proof of concept here: https://dtbaker.net/files/prevent-post-resubmit.php
此处的概念证明:https: //dtbaker.net/files/prevent-post-resubmit.php
I would still recommend a Post/Redirect/Get approach, but this is a novel JS solution.
我仍然会推荐 Post/Redirect/Get 方法,但这是一个新颖的 JS 解决方案。
回答by Moob
You should really use a Post Redirect Get pattern for handling this but if you've somehow ended up in a position where PRG isn't viable (e.g. the form itself is in an include, preventing redirects) you can hash some of the request parameters to make a string based on the content and then check that you haven't sent it already.
您确实应该使用 Post Redirect Get 模式来处理这个问题,但是如果您以某种方式最终处于 PRG 不可行的位置(例如表单本身在包含中,防止重定向),您可以散列一些请求参数根据内容制作一个字符串,然后检查您是否还没有发送它。
//create digest of the form submission:
$messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);
//and check it against the stored value:
$sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';
if($messageIdent!=$sessionMessageIdent){//if its different:
//save the session var:
$_SESSION['messageIdent'] = $messageIdent;
//and...
do_your_thang();
} else {
//you've sent this already!
}
回答by Mo'men Mohamed
I use this javascript line to block the pop up asking for form resubmission on refresh once the form is submitted.
我使用此 javascript 行来阻止在提交表单后要求在刷新时重新提交表单的弹出窗口。
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
Just place this line at the footer of your file and see the magic
只需将此行放在文件的页脚即可看到神奇之处
回答by Savoo
You can prevent form resubmission via a session variable.
您可以通过会话变量阻止表单重新提交。
First you have to set rand()
in a textbox and $_SESSION['rand']
on the form page:
首先,您必须rand()
在文本框和$_SESSION['rand']
表单页面上进行设置:
<form action="" method="post">
<?php
$rand=rand();
$_SESSION['rand']=$rand;
?>
<input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
Your Form's Other Field
<input type="submit" name="submitbtn" value="submit" />
</form>
After that check $_SESSION['rand']
with textbox $_POST['randcheck']
value
like this:
之后检查$_SESSION['rand']
文本框$_POST['randcheck']
值,如下所示:
if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
// Your code here
}
回答by Ibu
When the form is processed, you redirect to another page:
处理表单后,您重定向到另一个页面:
... process complete....
header('Location: thankyou.php');
you can also redirect to the same page.
您也可以重定向到同一页面。
if you are doing something like comments and you want the user to stay on the same page, you can use Ajax to handle the form submission
如果您正在做诸如评论之类的事情并且希望用户停留在同一页面上,则可以使用 Ajax 来处理表单提交
回答by Prasanth Bendra
Use header and redirect the page.
header("Location:your_page.php");
You can redirect to same page or different page.Unset $_POST after inserting it to Database.
unset($_POST);
使用标题并重定向页面。
header("Location:your_page.php");
您可以重定向到同一页面或不同的页面。将其插入数据库后取消设置 $_POST。
unset($_POST);
回答by Eugen Konkov
I found next workaround. You may escape the redirection after processing POST
request by manipulating history
object.
我找到了下一个解决方法。您可以在处理POST
请求后通过操作history
对象来逃避重定向。
So you have the HTML form:
所以你有 HTML 表单:
<form method=POST action='/process.php'>
<input type=submit value=OK>
</form>
When you process this form on your server you instead of redirecting user to /the/result/page
by setting up the Location
header like this:
当您在服务器上处理此表单时,您无需/the/result/page
通过设置这样的Location
标头来将用户重定向到:
$cat process.php
<?php
process POST data here
...
header('Location: /the/result/page');
exit();
?>
After processing POST
ed data you render small <script>
and the result /the/result/page
处理完POST
ed 数据后,您将呈现较小<script>
的结果/the/result/page
<?php
process POST data here
render the <script> // see below
render `/the/result/page` // OK
?>
The <script>
you should render:
在<script>
您应该呈现:
<script>
window.onload = function() {
history.replaceState("", "", "/the/result/page");
}
</script>
The result is:
结果是:
as you can see the form data is POST
ed to process.php
script.
This script process POST
ed data and rendering /the/result/page
at oncewith:
如您所见,表单数据已POST
写入process.php
脚本。
这个脚本程序POST
编数据,并绘制/the/result/page
一次有:
- no redirection
- no re
POST
data when you refresh page (F5) - no re
POST
when you navigate to previous/next page through the browser history
- 没有重定向
POST
刷新页面时没有重新数据(F5)POST
当您通过浏览器历史记录导航到上一页/下一页时没有重新
UPD
UPD
As another solution I ask feature requestthe Mozilla FireFoxteam to allow users to setup NextPage
header which will work like Location
header and make post/redirect/get
pattern obsolete.
作为另一种解决方案我问功能要求的Mozilla Firefox的团队,以允许用户设置NextPage
标头,会像Location
头和化妆post/redirect/get
模式已经过时了。
In short. When server process form POST
data successfully it:
简而言之。当服务器POST
成功处理表单数据时:
- Setup
NextPage
header instead ofLocation
- Render the result of processing
POST
form data as it would render forGET
request inpost/redirect/get
pattern
- 设置
NextPage
标题而不是Location
- 呈现处理
POST
表单数据的结果,因为它会GET
在post/redirect/get
模式中呈现请求
The browser in turn when see the NextPage
header:
浏览器依次看到NextPage
标题:
- Adjust
window.location
withNextPage
value - When user refresh the page the browser will negotiate
GET
request toNextPage
instead of rePOST
form data
window.location
用NextPage
值调整- 当用户刷新页面时,浏览器将协商
GET
请求NextPage
而不是重新POST
形成数据
I think this would be excelent if implemented, would not? =)
我认为这如果实施会很好,不是吗? =)
回答by Absolut
A pretty surefire way is to implement a unique ID into the post and cache it in the
一个非常可靠的方法是在帖子中实现一个唯一的 ID 并将其缓存在
<input type='hidden' name='post_id' value='".createPassword(64)."'>
Then in your code do this:
然后在您的代码中执行以下操作:
if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
$_SESSION['post_id'] = $_POST['post_id'];
//do post stuff
} else {
//normal display
}
function createPassword($length)
{
$chars = "abcdefghijkmnopqrstuvwxyz023456789";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i <= ($length - 1)) {
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
回答by Tanmoy Datta
This method works for me well, and I think this is the simplest one to do this job.
这种方法对我很有效,我认为这是完成这项工作的最简单的方法。
The general idea is to redirect the user to some other pages after the form submission, which would stop the form resubmission on page refresh. Still, if you need to hold the user on the same page after the form is submitted, you can do it in multiple ways, but here I am describing the javascript method.
一般的想法是在表单提交后将用户重定向到其他一些页面,这将在页面刷新时停止表单重新提交。尽管如此,如果您需要在表单提交后将用户保持在同一页面上,您可以通过多种方式来实现,但这里我描述的是 javascript 方法。
Javascript Method
Javascript 方法
This method is quite easy and blocks the pop up asking for form resubmission on refresh once the form is submitted. Just place this line of javascript code at the footer of your file and see the magic.
这种方法非常简单,一旦提交表单,就会阻止在刷新时要求重新提交表单的弹出窗口。只需将这行 javascript 代码放在文件的页脚,就可以看到神奇之处。
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>