PHP阻止没有javascript的后退按钮缓存重新提交

时间:2015-03-06 23:45:41

标签: php forms back

我有一个表单,用户输入数据并将其提交给自己。在我的代码中,我处理这些数据,然后再次重定向到自身,以防止刷新重新提交(我不使用PRG,因为URL可以加入书签)。

简单示例(index.php):

<?php
if (isset($_POST["submitted"])) {
    // do data processing

    header("location:index.php?success=1");
    die();
}
?>

<form action="#" method="post">
    <p><input type="text" name="foo"></p>
    <p><input type="submit" name="submitted"></p>
</form>

与此类问题(Prevent Form resubmission upon hitting back button)不同,我的问题不是按下后退按钮要求我重新提交。我的问题是,当我按下时,浏览器(特别是chrome)已缓存输入并显示它们。因此,用户可以再次单击“提交”按钮以向我的网站发送垃圾邮件/制作副本。

我查看了这样的问题(Prevent back button exploits? PHP),但我不想设置时间限制,并且唯一标识符不起作用,因为值是通过php粘贴的(隐藏输入不会保留值,因为它被粘贴并且php为每次访问生成一个新令牌(包括返回)。)

我可能会使用AJAX来解决这个问题(Preventing form resubmission),但是我无法想出一种优雅降级的方法&#34;如果javascript被禁用(&#34;你无法提交,因为你没有启用javascript,抱歉&#34;:D)。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

在表单页面上设置no-cache标头:

<?php
if (isset($_POST["submitted"])) 
{
    // do data processing
    header("Location: index.php?success=1");
    die();
}
else
{
    header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: no-cache');
}
?>

<form action="#" method="post">
    <p><input type="text" name="foo"></p>
    <p><input type="submit" name="submitted"></p>
</form>

现在填写值的表单不会被缓存。返回表单将导致必须刷新表单页面,这应该使值为空。

答案 1 :(得分:0)

如果用户返回时重新提交是您的主要问题,那么遵循PRG模式对您有好处。但请确保您不要混合页面以查看和提交处理程序。根据单一责任原则规则,混合这是一个坏主意。当你按照PRG模式时,我不认为URL可以被加入书签,除非你仍然在帖子处理程序上向用户显示某些内容(显示成功消息),然后你实际上没有关注PRG模式。

但是如果你仍然喜欢将它们混合在一起,那么@developerwjk应该可以解决这个问题。另一种方法是,您可以为每个帖子创建唯一标记(通过隐藏输入)。然后邮件处理程序应检查此令牌是否已由其他人提交。将唯一令牌放在会话中是好的,以便稍后查看。确保设置会话到期。这不应该导致再次提交重复数据。