屏蔽来自网页端的垃圾评论

上一篇提到我把 XML-PRC 的评论功能关掉了,但是效果并不明显,一晚上仍然有超过 20 条垃圾评论。和往常一样,这些垃圾评论被 Akismet 拦截下来,然后被我手动全部清除。

尽管 Akismet 的检测非常有效,几乎没有误伤的情况,但我依然觉得它有点大材小用了。Akismet 的工作原理是把每一条评论都发往 Akismet 的官方服务器,让服务器来判断是不是垃圾评论。它之所以高效是因为,Akismet 监控了大量 WordPress 博客的评论,一旦有某种模式的评论被认为是垃圾评论,所有启用了 Akismet 的博客都可以对那一类的垃圾进行过滤。这样略有一点用牛刀杀鸡的感觉。Akismet 会在网页中嵌入一些代码,虽然不大,但我对网页大小一直都很挑剔,能减则减;并且它会和其它的服务器通信,不仅增加了博客主机的负载,还消耗了更多的流量。

一定有一种更有效、更轻型的方法,可以用来检测并屏蔽这些垃圾评论。

以下是我的方法,它基于两点假设:

  1. 正常读者的浏览器都支持 Javascript。目前主流的浏览器都已支持并默认开启 Javascript,如果你所用的浏览器不支持它,那我也爱莫能助了。
  2. 正常读者都是通过评论框来写评论,而不是通过脚本自动填写的。基本信息如名字、邮箱等可以用脚本填写,这没有问题,但实际的评论内容也用脚本的话,那就说不过去了。另一方面,垃圾评论则有可能是机器自动生成、自动填写的,填写的方式基本是利用 Javascript 直接改评论内容。

基于以上的理论,我在 functions.php 中增加了以下代码:

这是两个全局的常量,用于后续的检测。它们用于生成一个随机数,在服务器端进行后续的检测。

以上代码在评论框中添加一个隐藏的元素“leonax-magic”,它的初始值是 0,当用户填写了评论的内容之后,它的值会变成另一个随机数字,大小介于上述的 $leonax_magic_lower 和 $leonax_magic_upper 之间。这个值有助于我们检测垃圾评论。

以上代码在评论提交之后进行检测,如果“leonax-magic”的值介于 $leonax_magic_lower 和 $leonax_magic_upper 之间,则表示该评论是正常的,反之则说明是垃圾评论。如果是垃圾评论,则直接报错(即在网页中会显示错误信息),而不是像 Akismet 一样存在数据库中。因为根据上面的假设,这样抓获的评论一定是垃圾评论,不需要再审核,于是就直接丢弃。

接下去是一些说明:

1. 为什么要用 $leonax_magic_lower 和 $leonax_magic_upper?
如果垃圾评论的机器蛮得聪明了,学会了在 HTTP 请求中添加 $leonax_magic 的值,我们可以通过改变 $leonax_magic_lower 和 $leonax_magic_upper 的值来继续阻止垃圾评论。

2. 这个机制有多么有效?
目前已使用超过48小时(至 11 月 28 日),没有一条垃圾评论漏网。


23 条评论 添加

  1. Akismet 据说会对服务器造成压力,而且会植入数据库一些有的没的东西

    而我遇过Akismet 误判数次,每次删垃圾评论前都要一条条看一下

  2. 网上有一个版本,叫小墙阻止垃圾评论。
    但有一个问题是,它每次都在网页上随机生成一个数字,破坏了页面缓存机制。
    你这个有没有这方面的问题?

    1. TL;DR,在不改动服务器端代码(PHP)的情况下,小墙和我的版本都不会影响页面缓存。

      我之前不知道这个插件,然后就去搜了一下。原作者的博客已关,坊间流传的版本最新的是 v1.9。这一版本和我的代码异曲同工,主要差别是,可能是受限于当时的技术(Wordpress 3.0 左右的版本),小墙的代码不太优雅,比如用了 ob_start() 和正则表达式,这些代码可能和后续版本不兼容。小墙的早期版本有一些性能问题,但 v1.9 貌似没什么问题。小墙的原理是把评论框的 id 改成了“w”,而原先的 id “comment”则作为检测垃圾评论的项。

      在我的代码中,如果你不改动 $leonax_magic_lower 和 $leonax_magic_upper 的值,则缓存没有问题,如果改了,则需要立即刷新缓存。

      1. 用Akismet不短时间了,貌似因为服务器的原因会拖累评论发表。这个方法目测还不错,等博主人肉体验三个月再来试试。 哈~

    1. 我后来又改过一些,现在评论字数必须大于五,并且要在一小时之内把评论发出去。不过和上面的代码本质上一样的,贴子内容就不改了。

        1. 我猜可以在 leonax_anti_spam_check 的第 7 行之前加上一段,比如:

          没有测试过,请慎用。

  3. 挺好用的,不过发现一个问题,如果登录了,不管怎么发,都会被判定为垃圾评论,请问这个问题如何解呢

发表评论

电子邮件地址不会被公开。 必填项已用*标注