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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:59:15  来源:igfitidea点击:

How to prevent form resubmission when page is refreshed (F5 / CTRL+R)

phphtmlformspostform-submit

提问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.replaceStateto 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

  1. Use header and redirect the page.

    header("Location:your_page.php");You can redirect to same page or different page.

  2. Unset $_POST after inserting it to Database.

    unset($_POST);

  1. 使用标题并重定向页面。

    header("Location:your_page.php");您可以重定向到同一页面或不同的页面。

  2. 将其插入数据库后取消设置 $_POST。

    unset($_POST);

回答by Eugen Konkov

I found next workaround. You may escape the redirection after processing POSTrequest by manipulating historyobject.

我找到了下一个解决方法。您可以在处理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/pageby setting up the Locationheader like this:

当您在服务器上处理此表单时,您无需/the/result/page通过设置这样的Location标头来将用户重定向到:

$cat process.php
<?php 
     process POST data here
     ... 
     header('Location: /the/result/page');
     exit();
?>

enter image description here

在此处输入图片说明

After processing POSTed data you render small <script>and the result /the/result/page

处理完POSTed 数据后,您将呈现较小<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:

结果是:

enter image description here

在此处输入图片说明

as you can see the form data is POSTed to process.phpscript.
This script process POSTed data and rendering /the/result/pageat oncewith:

如您所见,表单数据已POST写入process.php脚本。
这个脚本程序POST编数据,并绘制/the/result/page一次有:

  1. no redirection
  2. no rePOSTdata when you refresh page (F5)
  3. no rePOSTwhen you navigate to previous/next page through the browser history
  1. 没有重定向
  2. POST刷新页面时没有重新数据(F5)
  3. POST当您通过浏览器历史记录导航到上一页/下一页时没有重新

UPD

UPD

As another solution I ask feature requestthe Mozilla FireFoxteam to allow users to setup NextPageheader which will work like Locationheader and make post/redirect/getpattern obsolete.

作为另一种解决方案我问功能要求Mozilla Firefox的团队,以允许用户设置NextPage标头,会像Location头和化妆post/redirect/get模式已经过时了。

In short. When server process form POSTdata successfully it:

简而言之。当服务器POST成功处理表单数据时:

  1. Setup NextPageheader instead of Location
  2. Render the result of processing POSTform data as it would render for GETrequest in post/redirect/getpattern
  1. 设置NextPage标题而不是Location
  2. 呈现处理POST表单数据的结果,因为它会GETpost/redirect/get模式中呈现请求

The browser in turn when see the NextPageheader:

浏览器依次看到NextPage标题:

  1. Adjust window.locationwith NextPagevalue
  2. When user refresh the page the browser will negotiate GETrequest to NextPageinstead of rePOSTform data
  1. window.locationNextPage值调整
  2. 当用户刷新页面时,浏览器将协商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>