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

mar*_*zzz 22 html php 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>
Run Code Online (Sandbox Code Playgroud)

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

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

cor*_*ard 36

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

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

  • 这是你应该经常做的事情.这个模式甚至还有一个wiki页面:http://en.wikipedia.org/wiki/Post/Redirect/Get (7认同)

Ben*_*Ben 26

在显示表单时在会话中设置随机数,并将该数字放在隐藏字段中.如果发布的号码和会话号匹配,则删除会话,运行查询; 如果他们不这样做,重新显示表单,并生成一个新的会话号码.这是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 } ?>
Run Code Online (Sandbox Code Playgroud)

  • 会话过期的条件:if(!empty($ _ SESSION ["formid"])&& $ _POST ["formid"] == $ _SESSION ["formid"]) (2认同)

Cul*_*lly 5

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

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

<script>history.pushState({}, "", "")</script>
Run Code Online (Sandbox Code Playgroud)

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

  • 这是完美的答案。我想这应该是最好的答案。 (3认同)