PHP阻止返回按钮缓存重新提交而不使用javascript

PHP阻止返回按钮缓存重新提交而不使用javascript,php,forms,back,Php,Forms,Back,我有一个表单,用户在其中键入数据并将其提交给自己。在我的代码中,我处理这些数据,然后再次重定向到自身,以防止刷新重新提交(我不使用PRG,因为URL可以被标记为书签) 简单示例(index.php): 与此()之类的问题不同,我的问题不是按后退按钮要求我重新提交。我的问题是,当我按下back键时,浏览器(特别是chrome)缓存了输入并显示它们。因此,用户可以再次单击“提交”按钮以发送垃圾邮件/复制我的网站 我研究了类似于()的问题,但我不想设置时间限制,唯一标识符不起作用,因为值是由p

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

简单示例(index.php):


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

我研究了类似于()的问题,但我不想设置时间限制,唯一标识符不起作用,因为值是由php粘贴的(隐藏输入不会保留值,因为它是粘贴的,php会为每次访问(包括返回)生成一个新的令牌)

我可能可以使用AJAX来解决这个问题(),但如果禁用javascript,我想不出一种“优雅地降级”的方法(“你不能提交,因为你没有启用javascript,对不起”:D)


如何解决此问题?

在表单页上设置无缓存头:

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


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

如果用户返回时重新提交是您的主要问题,则遵循PRG模式对您有好处。但请确保不要将查看和提交处理程序的页面混合在一起。混合这是个坏主意,违背了单一责任原则。我不认为当您遵循PRG模式时,URL可以被书签将是一个问题,除非您仍然在post处理程序上向用户显示某些内容(例如显示成功消息),否则您实际上不遵循PRG模式


但是如果您仍然喜欢将两者混合使用,@developerwjk应该可以解决这个问题。另一种方法是,您可以为每个帖子创建唯一的令牌(通过隐藏输入)。然后,post处理程序应检查此令牌是否由其他人提交。在会话中放置唯一令牌是正确的,因此您可以稍后进行检查。确保设置了会话到期时间。这不应导致再次提交重复数据

@developerwjk在防范恶意意图时,不能依靠“浏览器”来尊重标题
<?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>