如何防止在PHP中提交表单时多次插入?

2022-08-30 14:24:41

有时用户可能会按两次,帖子入两次。Enter

除了检查是否已经有一个具有相同和的帖子之外,是否有解决方案可以防止这种情况?titlecontent


答案 1

此问题有几种解决方案:

  1. 使用 Javascript 在表单发布时禁用表单的提交按钮。这样做的缺点是,这绝对不是万无一失的方式。无需实际单击按钮即可轻松提交表单,并且这对于禁用了JavaScript的用户也不起作用。我绝对不会推荐这种方法。

    例:

    <script language="javascript">
    <!--
        function disableSubmitButton() {
            // you may fill in the blanks :)
        }
    -->
    </script>
    <form action="foo.php" method="post">
        <input type="text" name="bar" />
        <input type="submit" value="Save" onclick="disableSubmitButton();">
    </form>
    
  2. 使用 PHP 会话将会话变量(例如 $_SESSION['posttimer'])设置为 post 上的当前时间戳。在 PHP 中实际处理表单之前,请检查 $_SESSION['posttimer'] 变量是否存在,并检查某个时间戳差异(即:2 秒)。这样,您可以轻松过滤掉双重提交。

    例:

    // form.html
    <form action="foo.php" method="post">
        <input type="text" name="bar" />
        <input type="submit" value="Save">
    </form>
    
    // foo.php
    if (isset($_POST) && !empty($_POST)) 
    {
        if (isset($_SESSION['posttimer']))
        {
            if ( (time() - $_SESSION['posttimer']) <= 2)
            {
                // less then 2 seconds since last post
            }
            else
            {
                // more than 2 seconds since last post
            }
        }
        $_SESSION['posttimer'] = time();
    }
    
  3. 在每个 POST 上包含一个唯一的令牌。在这种情况下,您还可以将会话变量设置为要包含的令牌,然后在表单中呈现令牌。提交表单后,重新生成令牌。当提交的令牌与会话中的令牌不匹配时,表单已重新提交,应声明无效。

    例:

    // form.php
    <?php
        // obviously this can be anything you want, as long as it is unique
        $_SESSION['token'] = md5(session_id() . time());
    ?>
    <form action="foo.php" method="post">
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
        <input type="text" name="bar" />
        <input type="submit" value="Save" />
    </form>
    
    // foo.php
    if (isset($_SESSION['token']))
    {
        if (isset($_POST['token']))
        {
            if ($_POST['token'] != $_SESSION['token'])
            {
                // double submit
            }
        }
    }
    

答案 2

对 post 使用唯一的标记,以便每个 post/回发只处理一次。

禁用提交按钮不是一个很好的解决方案,因为人们可以关闭javascript,或者做其他奇怪的事情。客户端验证是一个良好的开端,但也应始终使用服务器端处理进行备份。


推荐