如何防止重复的帖子通过浏览器刷新


How to prevent duplicate posts via a browser refresh?

如果用户发布一个表单,然后单击浏览器刷新按钮,下面的操作是否会阻止数据库中意外的重复条目?

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' ) {
        try {
            // write to database
        } catch($e) {
            // error reporting
        }
    }
?>

使用Post-Redirect-Get模式-总是在数据成功提交后重定向。

不,因为如果他们单击刷新按钮(或后退/前进,无论什么),浏览器将尝试再次POST。你需要的是Post/Redirect/Get模式。注意,这只会防止通过导航重复提交。如果你想防止多次点击表单提交的重复提交,你必须使用javascript在post尝试期间以某种方式禁用该按钮。

一些代码:

<?php
   if ('POST' == $_SERVER['REQUEST_METHOD']) {
      //do processing
      //303 forces a GET request
      header("Location: thank-you-page", true, 303);
      exit;
   }
   else {
      //handle bad page visit.
   }
?>

我没有看到任何代码做任何事情来区分第一个帖子和重复的帖子。您应该做的是在处理POST后将浏览器重定向到另一个URL,这样如果它们按刷新,它们就不会刷新表单的目标并再次张贴。

您应该使用Dan Grossman的方法,总是在POST操作之后重定向。这也是另一个选项,它增加了额外的安全性:

向表单添加一个一次性令牌,并将其保存到$_SESSION -变量中。然后,如果它被使用(表单被提交),将其从会话中删除(或创建一个新的令牌)。如果再次发送表单,则两个令牌不匹配,并且您有一个重复的条目(例如,您可以忽略第二个)。