问题描述
有时用户可能会按 Enter
两次,并将该帖子插入两次。
有没有一个解决方案来防止这个,除了检查是否已经有相同的 title
和 content
的帖子?
最佳解决办法
这个问题有几种解决方案:
-
使用 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>
-
使用 PHP sessions 将会话变量 (例如 $ _SESSION [‘posttimer’]) 设置为 post 的当前时间戳。在 PHP 中实际处理表单之前,请检查 $ _SESSION [‘posttimer’] 变量是否存在,并检查某个时间戳差异 (IE: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(); }
-
在每个 POST 上包含唯一的令牌。在这种情况下,您还可以将会话变量设置为要包含的令牌,然后以该表单呈现令牌。一旦提交表单,您就可以使用 re-generate 令牌。当提交的令牌与您的会话中的令牌不匹配时,该表单已被 re-submitted,并且应被声明为无效。
例:
// 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 } } }
次佳解决办法
使用唯一的标记与帖子,以便每个 post /回发只处理一次。
禁用提交按钮不是一个很好的解决方案,因为人们可能会关闭 javascript,或做其他奇怪的事情。客户端验证是一个很好的开始,但是始终应该使用服务器端处理进行备份。
第三种解决办法
生成一个独特的,one-time 使用密钥提交与表单。
依靠 Javascript 是一个坏主意,因为它可能已被用户在客户端禁用。使用密钥方案,当服务器收到提交时,该密钥的提交可以被锁定。您可以回复重复的提交,但您喜欢。
对于这种工作方式,键必须是独一无二的,很难预测。否则由于关键碰撞,某些形式可能被锁定。因此,您不必为每个表单提交跟踪密钥,并避免冲突,密钥应该与该用户的会话过期。要注意的另一件事是,如果恶意用户能够预测密钥,您的代码可能会受到某种劫持或 DOS 漏洞的攻击。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。