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

时间:2011-04-17 00:08:52

标签: php html forms

我认为这个问题经常发生在Web应用程序开发上。但我会尝试详细解释我的问题。

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

<?
    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>

提交表单后,数据将插入数据库,并生成消息 Operation Done 。然后,如果我刷新页面,数据将再次插入数据库。

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

9 个答案:

答案 0 :(得分:35)

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

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

答案 1 :(得分:25)

在显示表单时在会话中设置随机数,并将该数字放在隐藏字段中。如果发布的号码和会话号匹配,则删除会话,运行查询;如果他们不这样做,重新显示表单,并生成一个新的会话号码。这是XSRF令牌的基本思想,您可以在此处详细了解它们及其在安全性方面的用途:http://en.wikipedia.org/wiki/Cross-site_request_forgery

以下是一个例子:

<?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 } ?>

答案 2 :(得分:3)

像这样:

<?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>

答案 3 :(得分:1)

我认为这更简单,

<强> page.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>

答案 4 :(得分:1)

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

成功提交表单后,请在页面上添加以下Javascript:

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

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

答案 5 :(得分:0)

我们在设计php表单数量的网络应用程序上工作。编写另一个页面以获取数据并为每个表单提交数据是很麻烦的。为避免重新提交,我们在每个表格中创建了一个“random_check”字段,该字段标记为“唯一”。

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

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

之后您可以显示错误,如

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

答案 6 :(得分:0)

无需重定向...

替换die();
isset(! $_POST['name']);

,将isset设置为isset不等于$ _POST [&#39; name&#39;],因此当您刷新它时,它将不会再添加到您的数据库,除非您再次单击提交按钮。

<?
    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>

答案 7 :(得分:0)

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

因此,通过治愈其根源来解决这个问题的想法。

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

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"]);"> 

答案 8 :(得分:0)

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

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