【问题标题】:Avoiding form resubmit in php when pressing f5按 f5 时避免在 php 中重新提交表单
【发布时间】:2009-04-06 18:06:54
【问题描述】:

我的网站上有以下代码(使用 php 和 smarty)来尝试避免在按 f5 时重新提交表单:

if ($this->bln_added == false) {
    if (isset($_POST['submit'])) {
        $this->obj_site->obj_smarty->assign('title', $_POST['tas_heading']);
        $this->obj_site->obj_smarty->assign('desc', $_POST['tas_description']);
    }
} else {
    $this->obj_site->obj_smarty->assign('title', '');
    $this->obj_site->obj_smarty->assign('desc', '');
    unset($_POST);
}

bln_added 默认为 false,但一旦表单提交成功,就会变为 true。 smarty 变量 title 和 desc 在模板中用于保留表单内容,以防出现用户错误并且他们需要更改输入的内容。

如果表单提交成功它设置bln_added = true,所以第二段代码不仅要清除表单字段,还要清空$_POST。但是,如果我按 f5,帖子数据仍然存在。

有什么想法吗?

【问题讨论】:

    标签: php form-submit


    【解决方案1】:

    您的方法理论上可行,但还有更简单的方法。

    成功提交表单后,执行重定向。去哪里并不重要,但它会清除 $_POST。

    header('Location: http://www.example.com/form.php');
    

    在你的情况下,听起来你想重定向到你已经在的页面。如果要显示确认消息,请将 $_GET 参数附加到 URL。

    希望对你有帮助,

    汤姆

    【讨论】:

    • 很好的答案,PRG 绝对是要走的路:en.wikipedia.org/wiki/Post/Redirect/Get
    • 我需要标题的完整网址吗?
    • 刚试了一下,它与应用程序中其他地方设置的标头冲突。我没有全部写出来,所以不知道去哪里停止设置。
    • 听起来你在标题之前有输出。你可能会死('这里');并查看应用程序正在发送什么。
    • 我相信完整的 URL 不是必需的,当您提供相对 URL 时,PHP 或 Apache 会将其解析为绝对 URL 以发送给客户端(不确定这需要链中的哪个阶段地点)。
    【解决方案2】:

    您正在寻找的答案是这个神奇的一班轮: header('Location: '.$_SERVER['HTTP_REFERER']);

    例如

    if(isset['submit']){
        //insert database
        header('Location: '.$_SERVER['HTTP_REFERER']);
    }
    

    【讨论】:

      【解决方案3】:

      解决方案是一种俗称Post/Redirect/Get的模式

      【讨论】:

        【解决方案4】:

        我发现最好的方法是使用 javascript 和 css。常用php重定向方法header('Location:http://www.yourdomain.com/url);会起作用,但它会在不同的框架和 cms(如 wordpress、drupal 等)中导致警告“警告:无法修改标头信息 - 标头已发送”。所以我的建议是遵循以下代码

        echo '<style>body{display:none;}</style>'; 
        echo '<script>window.location.href = "http://www.siteurl.com/mysuccesspage";</script>'; 
        exit;
        

        样式标签很重要,否则用户可能会觉得页面加载了两次。如果我们使用 style 标签 body display none 然后刷新页面,那么用户体验会像 php header('Location: ....);

        我希望这会有所帮助:)

        【讨论】:

          【解决方案5】:

          处理表单的最佳方式是使用自行提交和重定向。像这样的:

          if (isset($_POST)) {
            // Perform your validation and whatever it is you wanted to do
            // Perform your redirect
          }
          
          // If we get here they didn't submit the form - display it to them.
          

          使用CodeIgniter framework

          function index() {
            $this->load->library('validation');
            // Your validation rules
          
            if ($this->form_validation->run()) {
              // Perform your database changes via your model
              redirect('');
              return;
            }
            // The form didn't validate (or the user hasn't submitted)
            $this->load->view('yourview');
          }
          

          【讨论】:

            【解决方案6】:

            您可以将表单提交重写为 AJAX 方式。如果您需要显示 HTML 内容,请以 JSON 格式返回并使用 JavaScript(例如 jQuery)插入。

            【讨论】:

              【解决方案7】:

              我通过以下方式解决了这个问题(在 php 中):

              1. 在表单中添加一个不基于time()的唯一标识符(id+counter)(!!!)

              2. 发布到一个单独的文件 (postform.php),该文件检查具有该唯一标识符的会话

              3. a) 如果未找到具有唯一标识符的会话:发布到数据库并使用唯一标识符填充会话

                b) 如果找到具有唯一标识符的会话:什么也不做

              4. 在任一 3a/3b 重定向到带有标题的结果页面后('位置:http://mydomain.com/mypage')

              结果是:
              刷新/返回按钮没有重新提交操作,只有双击返回按钮重新提交警告(但没有重新提交操作)

              【讨论】:

              • 谢谢保罗,我有一个基本的想法,为什么我们不应该在同一个页面中使用表单提交。以前我使用表单提交到同一页面。处理完表单后,我用一些get参数将它重定向到self。
              【解决方案8】:

              成功发布操作后使用标题位置

              header('Location: '.$_SERVER['HTTP_REFERER']);
              

              【讨论】:

                【解决方案9】:

                如果我在代码末尾使用 header() 或 exit() 对我有用,例如,在我保存一些数据之后。

                【讨论】:

                  【解决方案10】:

                  帖子后的标题重定向是必要的,但不够。

                  在PHP端成功提交表单后,执行重定向。例如。 header('位置:http://www.example.com/form.php');

                  但这还不够。一些用户按两次链接(双击)。需要在第一次点击后禁用提交按钮的 JavaScript。

                  【讨论】:

                    【解决方案11】:

                    试试我自己的,也许它不是最好的解决方案(快速完成),但我已经测试过它并且它有效。在 Chrome 上测试。 Click to see how it looksBR

                     <?php 
                    session_start(); // Start session
                    ?>
                    <html>
                     <head>
                      <title>
                        Test
                      </title>
                     </head>
                     <body>
                       <form name="test" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
                       <input type="text" name="name"><br>
                       <input type="submit" name="submit" value="Submit Form"><br>
                      </form>
                    
                      <?php
                    
                      if(isset($_POST['submit']))
                        {
                         $_SESSION['name'] = $_POST['name']; //  Assign $_POST value to $_SESSION variable
                          header('Location: refresh.php'); // Address of this - reloaded page - in this case similar to PHP_SELF
                        } else session_destroy(); // kill session, depends on what you want to do / maybe unset() function will be enough
                    
                      if(isset($_SESSION['name']))
                        {
                         $name = $_SESSION['name'];
                    
                         echo "User Has submitted the form and entered this name : <b> $name </b>";
                         echo "<br>You can use the following form again to enter a new name."; 
                        }
                      ?>
                     </body>
                    </html>
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-06-05
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多