php 避免由于页面刷新而提交的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5690541/
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 22:13:45  来源:igfitidea点击:

Best way to avoid the submit due to a refresh of the page

phphtmlforms

提问by markzzz

I think that this problem occurs often on a web application development. But I'll try to explain in details my problem.

我认为这个问题经常发生在 web 应用程序开发中。但我会尽量详细解释我的问题。

I'd like to know how to correct this behavior, for example, when I have a block of code like this :

我想知道如何纠正这种行为,例如,当我有这样的代码块时:

<?
    if (isset($_POST['name'])) {
        ... operation on database, like to insert $_POST['name'] in a table ...
        echo "Operation Done";
        die();
    }

?>

<form action='page.php' method='post' name="myForm">
    <input type="text" maxlength="50" name="name" class="input400" />
    <input type="submit" name="Submit" />
</form>

When the form gets submitted, the data get inserted into the database, and the message Operation Doneis produced. Then, if I refreshed the page, the data would get inserted into the database again.

当表单被提交时,数据被插入到数据库中,并产生消息操作完成。然后,如果我刷新页面,数据将再次插入到数据库中。

How this problem can be avoided? Any suggestion will be appreciated :)

如何避免这个问题?任何建议将不胜感激:)

回答by coreyward

Don't show the response after your create action; redirect to another page after the action completes instead. If someone refreshes, they're refreshing the GET requested page you redirected to.

不要在创建操作后显示响应;操作完成后重定向到另一个页面。如果有人刷新,他们正在刷新您重定向到的 GET 请求页面。

// submit
// set success flash message (you are using a framework, right?)
header('Location: /path/to/record');
exit;

回答by Ben

Set a random number in a session when the form is displayed, and also put that number in a hidden field. If the posted number and the session number match, delete the session, run the query; if they don't, redisplay the form, and generate a new session number. This is the basic idea of XSRF tokens, you can read more about them, and their uses for security here: http://en.wikipedia.org/wiki/Cross-site_request_forgery

显示表单时在会话中设置一个随机数,并将该数字放入隐藏字段中。如果发布号和会话号匹配,则删除会话,运行查询;如果没有,则重新显示该表单,并生成一个新的会话编号。这是 XSRF 令牌的基本思想,您可以在此处阅读有关它们的更多信息以及它们在安全方面的用途:http: //en.wikipedia.org/wiki/Cross-site_request_forgery

Here is an example:

下面是一个例子:

<?php
session_start();

if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"])
{
    $_SESSION["formid"] = '';
    echo 'Process form';
}
else
{
    $_SESSION["formid"] = md5(rand(0,10000000));
?>
    <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
    <input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" />
    <input type="submit" name="submit" />
</form>
<?php } ?>

回答by Cully

I ran into a similar problem. I need to show the user the result of the POST. I don't want to use sessions and I don't want to redirect with the result in the URL (it's kinda secure, I don't want it accidentally bookmarked). I found a pretty simple solution that should work for the cases mentioned in other answers.

我遇到了类似的问题。我需要向用户展示 POST 的结果。我不想使用会话,也不想使用 URL 中的结果重定向(它有点安全,我不希望它被意外添加书签)。我找到了一个非常简单的解决方案,它应该适用于其他答案中提到的情况。

On successfully submitting the form, include this bit of Javascript on the page:

成功提交表单后,在页面上包含以下 Javascript:

<script>history.pushState({}, "", "")</script>

It pushes the current URL onto the history stack. Since this is a new item in history, refreshing won't re-POST.

它将当前 URL 推送到历史堆栈上。由于这是历史上的新项目,刷新不会重新发布。

回答by Karl Laurentius Roos

Like this:

像这样:

<?php
if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){
    // can't submit again
}
else{
    // submit!
    $_SESSION['uniqid'] = $_POST['uniqid'];
}
?>

<form action="page.php" method="post" name="myForm">
    <input type="hidden" name="uniqid" value="<?php echo uniqid();?>" />
    <!-- the rest of the fields here -->
</form>

回答by Sherin Jose

I think it is simpler,

我觉得比较简单

page.php

页面.php

<?php
   session_start();
   if (isset($_POST['name'])) {
        ... operation on database, like to insert $_POST['name'] in a table ...
        $_SESSION["message"]="Operation Done";
        header("Location:page.php");
        exit;
    }
?>

<html>
<body>
<div style='some styles'>
<?php
//message here
echo $_SESSION["message"];
?>
</div>
<form action='page.php' method='post'>
<!--elements-->
</form>
</body>
</html>

回答by MostHost LA

So, for what I needed this is what works.

所以,对于我所需要的,这就是有效的。

Based on all of the above solutions this allows me to go from a form to another form, and to the n^ form , all the while preventing the same exact data from being "saved" over and over when a page is refreshed (and the post data from before lingers onto the new page).

基于上述所有解决方案,这允许我从一个表单转到另一个表单,然后转到 n^ 表单,同时防止在刷新页面时一遍又一遍地“保存”相同的确切数据(以及将之前的数据发布到新页面上)。

Thanks to those who posted their solution which quickly led me to my own.

感谢那些发布他们的解决方案的人,这些解决方案很快让我找到了自己的解决方案。

<?php
//Check if there was a post
if ($_POST) {
//Assuming there was a post, was it identical as the last time?
   if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) {
//No, Save
   } else {
//Yes, Don't save
   }
} else {
//Save
}
//Set the session to the most current post.
$_session['pastData'] = $_POST;
?>

回答by Sandhu

We work on web apps where we design number of php forms. It is heck to write another page to get the data and submit it for each and every form. To avoid re-submission, in every table we created a 'random_check' field which is marked as 'Unique'.

我们致力于设计大量 php 表单的 Web 应用程序。编写另一个页面来获取数据并为每个表单提交数据真是太糟糕了。为了避免重新提交,我们在每个表中创建了一个标记为“唯一”的“random_check”字段。

On page loading generate a random value and store it in a text field (which is obviously hidden).

在页面加载时生成一个随机值并将其存储在文本字段中(显然是隐藏的)。

On SUBMIT save this random text value in 'random_check' field in your table. In case of re-submission query will through error because it can't insert the duplicate value.

在提交时,将此随机文本值保存在表中的“random_check”字段中。如果重新提交查询将通过错误,因为它无法插入重复值。

After that you can display the error like

之后,您可以显示如下错误

if ( !$result ) {
        die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' );
}

回答by Guest

No need to redirect...

不需要重定向...

replace die();with

替换die();

isset(! $_POST['name']);

, setting the isset to isset not equal to $_POST['name'], so when you refresh it, it would not add anymore to your database, unless you click the submit button again.

,将isset设置为isset不等于$_POST['name'],所以当你刷新它时,它不会再添加到你的数据库中,除非你再次点击提交按钮。

<?
    if (isset($_POST['name'])) {
        ... operation on database, like to insert $_POST['name'] in a table ...
        echo "Operation Done";
        isset(! $_POST['name']);
    }

?>

<form action='page.php' method='post' name="myForm">
    <input type="text" maxlength="50" name="name" class="input400" />
    <input type="submit" name="Submit" />
</form>

回答by Amul

This happen because of simply on refresh it will submit your request again.

发生这种情况是因为只需刷新它就会再次提交您的请求。

So the idea to solve this issue by cure its root of cause.

所以想通过根治来解决这个问题。

I mean we can set up one session variable inside the form and check it when update.

我的意思是我们可以在表单中设置一个会话变量并在更新时检查它。

if($_SESSION["csrf_token"] == $_POST['csrf_token'] )
{
// submit data  
}

//inside from 

$_SESSION["csrf_token"] = md5(rand(0,10000000)).time(); 

<input type="hidden" name="csrf_token" value=" 
htmlspecialchars($_SESSION["csrf_token"]);"> 

回答by Vikas Gore

I think following is the better way to avoid resubmit or refresh the page.

我认为以下是避免重新提交或刷新页面的更好方法。

$sample = $_POST['submit'];
if ($sample == "true") 
 {
//do it your code here
$sample = "false";
 }