如何防止点赞/踩按钮的自动点击垃圾邮件?

3

我有一个赞同按钮,用户可以点击并注册投票。再次点击此按钮将取消投票。

因此,每次按下此按钮都会进行一次数据库写入。如果连续使用自动点击器点击此按钮,则会发生连续的数据库调用。我想要避免这种情况发生。

我该怎么办?

顺便提一句,当点击赞同按钮时,我正在向后端(运行Django)发送ajax查询。


你可以在每次点击时使用 setTimeoutclearTimeout,这样当用户点击之前的 Timeout 就会被取消,只有在一段时间内没有点击后才会进行 ajax 调用。 - Moritz Roessler
如果有人禁用了cookies和javascript,那么这可能很难停止 :) - Rickard Zachrisson
如果JS被禁用,我认为点击事件也不应该被触发。显然,您可以调用服务器端方法,但这是另一个问题,与自动点击器无关。 - Abaco
5个回答

3

您真的希望在服务器上检查此内容,因此即使有人禁用javascript也无妨。

如果您正在使用PHP,则有一种选择是在投票之间设置时间限制。例如,每分钟只允许一次投票。

因此,在每次投票时,将投票时间存储在会话变量中,然后如果在时间限制内,则忽略后续投票:

//on vote
$now=date('U');
if(!isset($_SESSION['lastvote']) || $now - $_SESSION['lastvote']<LIMIT){
    $_SESSION['lastvote']=$now;
    // do database call

}else{
    //throw error
}

1
谢谢。这是唯一正确的答案。JavaScript不应该处理这个。 - Ian
玩得开心,与那些不断调用URL的机器人一起玩吧;-) - mawimawi

1

可能最简单的方法是在单个操作运行时禁用按钮。

为了实现这一点,假设您正在使用JQuery ajax请求调用“upvote”/“downvote”方法,您只需要:

$("#upvoteButton").click(function)
{
    $("#upvoteButton").attr("disabled");
    $.ajax({
      url: 'url/upvote.extension',
      success: function(data) {
        $("#upvoteButton").removeAttr("disabled");
      }
    });
}

这样每个标签页/窗口只发送和解决一个请求。

谢谢!一个疑问。一旦前一个请求的响应完成,这是否允许发送另一个请求? - user1912328
@user1912328 这正是应该发生的事情。虽然可能应该包括一个“error”选项,在其中执行与“success”中相同的代码。 - Ian

0

简单的方法:

<button id="upvote" onclick="upvote(this)">Up</button>

<script>
   var upvote = function(x){
      $(x).removeAttr('onclick'); //if you click this button again, it will do nothing

      //call ajax to do something here...
      //...............
      //after finishing, add attribute onclick to the button
      $(x).attr('onclick', 'upvote(this)')
   };
</script>

0

如果您相信用户接受cookie,您可以将点击与对象ID和时间戳一起存储在会话中,并测试用户是否在最后n秒内单击了投票按钮。

您还可以使用JavaScript禁用网页上的投票按钮,并在n秒后再次启用以撤销投票。

这两个建议都取决于使用启用JavaScript或启用Cookie的浏览器的用户。

如果您必须考虑只是重复向服务器发送URL的机器人,则需要采用不同的方法-例如检查当前IP地址是否在最后n秒内调用了URL,并引发403 Forbidden HTTP错误或其他错误。


0
如果你会使用setTimeout,你可以尝试像这样的东西:
var toggleVote = (function () {
  var voted = false,timeout;
  return function () {
     if( timeout )
       clearTimeout(timeout)

     voted = !voted

      timeout = setTimeout(function() {
        console.log("Ajax call - vote : " + voted)
      },400)
    }
  })()

document.getElementById("vote").addEventListener("click",toggleVote)

这是一个关于JSBin的例子:
试着点击“Click me” div。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接