【问题标题】:PHP avoid browser reposting $_POST on page refresh?PHP避免浏览器在页面刷新时重新发布$_POST?
【发布时间】:2012-12-03 01:48:38
【问题描述】:

我想知道我可以使用哪些技术来避免用户在刷新页面并再次选择提交时两次发布表单?

例如我在 regiter.php 中有表单并在 register.php.

中处理它

1st 我可以在另一个文件中处理,例如register_process.php 并重定向到 register.php,但是我必须创建大约 20 个新页面并重新定位大量代码,我不想要那个选项。

第二次我可以玩 headers 我不记得确切的技巧,但有一些糟糕的体验 - 用户在刷新页面后看到旧数据...

3rd 我可以在成功后重定向到一些 dummy.php 并从 dummy.php 跳回 register.php 那么即使他们刷新页面浏览器也不会重新发布,但它并不能防止他们使用 后退按钮 并选择重新发布,我知道我可以使页面过期,但我发现让我和其他用户看到页面过期错误的烦人体验。

4th在页面加载后为每个表单使用一些唯一的“访问密钥”,该页面将随表单一起发布,并且一旦使用就无法重复使用,但是我对该功能的逻辑有点挣扎。如果不将其存储在 MySQL 数据库中,如何知道密钥已被使用,我认为基于时间的访问也不是很好,因为有些用户在页面打开和表单提交之间可能需要很长时间。

我需要更多关于如何避免用户再次提交表单的建议。

【问题讨论】:

    标签: html post refresh


    【解决方案1】:

    试试这个:

    <?php
    session_start();
    if( strcasecmp($_SERVER['REQUEST_METHOD'],"POST") === 0) {
      $_SESSION['postdata'] = $_POST;
      header("Location: ".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']);
      exit;
    }
    if( isset($_SESSION['postdata'])) {
      $_POST = $_SESSION['postdata'];
      unset($_SESSION['postdata']);
    }
    

    这基本上会保存 POST 数据并导致浏览器重新请求为 GET 请求。

    【讨论】:

    • 我做了类似的事情,但是使用了更多的代码行:) 问题是如果他们在提交表单之前刷新页面,$_SESSION['postdata'] 将不再存在使用strcasecmp($_SERVER['REQUEST_METHOD'],"POST") 代替$_SERVER['REQUEST_METHOD'] == "POST" 有什么好处?
    【解决方案2】:

    第五。使用 AJAX 或 jQuery,当在页面上单击表单时,在后台提交该数据。向屏幕输出响应。将该表单标记为已提交,或保存到会话中,当他们刷新时,他们将无法再次提交该表单。

    在我看来,无论如何这是最好的方法。我有一个包含 20 个或更多表格的记分牌,它可以很好地发送数据而无需刷新。您可以返回响应并使页面看起来非常专业。使用 jQuery,您还可以使用一些很棒的表单验证来确保他们正在提交所需的字段。

    【讨论】:

    • 不,谢谢,我不想使用任何形式的 JavaScript,因为只有 html 和 php 的兼容性问题
    【解决方案3】:

    我认为最好的解决方案是这样的:
    * 创建发布数据的 md5 或 base64
    * 将此哈希与会话变量进行比较(我们称之为 $_SESSION['repost'])
    * 如果哈希匹配,则跳过此保存应执行的任何操作并输出警告
    * 如果哈希不匹配,或者哈希不存在
    * 使用当前哈希分配会话变量
    * 做任何保存应该做的事情

    【讨论】:

    • base64 创建散列,但它将 8 位数据编码为与代码页无关的 ASCII 字符。使用 base64 编码 8mb 的数据将大于 8mb,创建 8mb 数据的 md5 哈希将导致 16 字节长的哈希。
    【解决方案4】:

    当您考虑第一个选项时,我不知道您网站的设计(编程设计^^),但您应该只需要一个页面。假设你用所有参数调用redirect.php,你应该调用你的控制器,你的控制器应该知道不管参数如何处理它们。

    在编程时能够做一些抽象和良好的设计是一个好习惯,它在这些情况下很有帮助。

    【讨论】:

    • 我一直在考虑这个问题,但仍在考虑最好的办法。
    【解决方案5】:

    另一种方法是将最后一个帖子存储在会话变量中,并检查是否相等,如下所示:

    <?php
    ... program ...
    if ($_SESSION['PREPOST'] == $_POST) {
        // DO SOMETHING
    }
    ... program ...
    $_SESSION['PREPOST'] = $_POST;
    ?>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-12
      • 2011-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 2023-03-27
      相关资源
      最近更新 更多