【问题标题】:How to prevent multiple form submission on multiple clicks in PHP如何防止在 PHP 中多次单击时提交多个表单
【发布时间】:2011-06-04 14:01:13
【问题描述】:

PHP中如何防止多次点击提交多个表单

【问题讨论】:

标签: php button click submit


【解决方案1】:

您也可以通过设置一个独特的字段(例如电子邮件/用户名或注册号)来防止这种情况。然后将新字段与数据库中的现有字段进行测试,如果匹配,则用户之前已注册,表单提交应停止,否则继续提交表单。

【讨论】:

    【解决方案2】:

    我在 action.php 上做如下操作

    if($_SESSION && isset($_SESSION['already_submitted'])) {
    
      # If already submitted just redirect to thank you page
    
    } else {
    
        # If first submit then assign session value and process the form
        $_SESSION['already_submitted'] = true;
    
        # Process form
    
    }
    

    注意:始终使用 session_start(); 在标头中启动会话

    【讨论】:

      【解决方案3】:

      你能隐藏点击按钮吗?它不会影响表单处理(我知道问题在于立即禁用按钮),但它基本上会做同样的事情。如果您真的担心它,您甚至可以只显示另一个实际上不执行任何操作的按钮。可能是一种非常规的解决方法,但仍然是一种解决方法。

      【讨论】:

      • 如果用户通过按回车键或应用程序中的某些内置 JavaScript(例如form.submit())提交表单怎么办?为确保表单不会同时重新提交两次(或多次),应该有提交的标识符并跟踪它们的完整性。如果您要生成 ID,我建议您使用这个 API (api.cloudianos.com/genToken),它以提供唯一的(用于中短期)int + char 字符串而闻名。
      【解决方案4】:

      我建议不要禁用提交按钮,因为在临时网络问题(即请求根本没有通过)的情况下,如果用户选择中止提交(Esc键/停止按钮),他将无法提交一旦网络服务已恢复,则必须重新加载页面并再次填写所有表单条目。

      【讨论】:

        【解决方案5】:

        使用每次显示表单时生成的唯一令牌,并且只能使用一次;防止CSRFreplay 攻击也很有用。 一个小例子:

        <?php
        session_start();
        
        /**
         * Creates a token usable in a form
         * @return string
         */
        function getToken(){
          $token = sha1(mt_rand());
          if(!isset($_SESSION['tokens'])){
            $_SESSION['tokens'] = array($token => 1);
          }
          else{
            $_SESSION['tokens'][$token] = 1;
          }
          return $token;
        }
        
        /**
         * Check if a token is valid. Removes it from the valid tokens list
         * @param string $token The token
         * @return bool
         */
        function isTokenValid($token){
          if(!empty($_SESSION['tokens'][$token])){
            unset($_SESSION['tokens'][$token]);
            return true;
          }
          return false;
        }
        
        // Check if a form has been sent
        $postedToken = filter_input(INPUT_POST, 'token');
        if(!empty($postedToken)){
          if(isTokenValid($postedToken)){
            // Process form
          }
          else{
            // Do something about the error
          }
        }
        
        // Get a token for the form we're displaying
        $token = getToken();
        ?>
        <form method="post">
          <fieldset>
            <input type="hidden" name="token" value="<?php echo $token;?>"/>
            <!-- Add form content -->
          </fieldset>
        </form>
        

        将它与重定向相结合,这样您就可以保持完美的向后和向前行为。 有关重定向的更多信息,请参阅POST / redirect / GET 模式。

        【讨论】:

        • 有人知道这段代码有什么问题吗,比如安全问题?
        • 我认为 $postedToken = filter_input(INPUT_POST, 'token'); 上缺少过滤器
        【解决方案6】:

        你可以添加这样的东西

        &lt;input type="hidden" name="form-token" value="someRandomNumber"&gt;

        然后在后端,您有一种识别多个表单提交的保存方法。当然,这个解决方案有一些包袱,因为你必须删除你知道已经完成处理的表单令牌等等......

        在大多数情况下,禁用的表单可以解决问题,例如通过禁用按钮或将return false 添加到表单提交事件(但不确定在没有 jQuery 的情况下这是否有效)。

        【讨论】:

        • 哦,好吧,看来我的回答有点晚了... 支持其他答案
        【解决方案7】:

        您可以在第一次点击后禁用按钮(使用 JavaScript),还可以检查后端(以防万一他们禁用了 JavaScript)检查他们是否最近提交。

        有很多不同的方法可以在后端进行检查。一种方法是在他们第一次单击时设置会话变量,这可以让系统知道它正在处理。如果他们点击了第二次、第三次或第四次,那么它可以只检查会话变量,如果这表明它已经被点击了,它就不会处理。

        这只是一个示例 - 您可以以此为起点。

        【讨论】:

          猜你喜欢
          • 2023-03-22
          • 1970-01-01
          • 1970-01-01
          • 2014-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多