每个博客主或者网站都会受到各式各样的垃圾留言骚扰。如果网站不及时清理这些垃圾留言,那么整个网站的可读性将会变得越来越糟糕,最后完全被垃圾浏览给占领了。
现在博客使用的是 WordPress,使用的是一个官方的插件 Akismet,这个程序还不错,通过后台大数据分析来识别垃圾评论。
不过除了 Akismet,我还有安装另外一个插件,这个插件很小巧,并且我觉得思路很不错。通过这两个插件来可以过滤很多的垃圾评论。
作者的思路是这样的:
为什么人类应该通过填充验证码(CAPTCHA)证明他们是人类?应该是让机器人通过 JavaScript 来证明他们不是机器人!
下面说说这个插件 anti-spam 使用的算法。
这个算法是基于 2 个方法:不可见的 JS 验证码(invisible js-captcha)
和不可见的输入框陷阱(invisible input trap)
。
不可见的 JS 验证码 invisible js-captcha
不可见的 JS 验证码(invisible js-captcha)
方法基于一个事实:机器人在他们的在程序中不会执行 JavaScript 代码。
所以默认在输出 HTML 评论框的时候,加入了一个隐藏的问题和输入框,问题是今年是公元 xxxx 年。
如果用户访问网站,这个输入框答案会被 JavaScript 自动回答,并且会被 JavaScript 和css 的手段隐藏起来,不让用户看到。
如果机器人去填写答案没有填写正确,那么就会被判定是垃圾信息。
作者实现很鸡贼,其实这里有两个输入框,一个输入框是正确的答案,一个输入框是错误的答案。
<p class="antispam-group antispam-group-q" style="clear: both;"> <label>Current ye@r <span class="required">*</span></label> <input type="hidden" name="antspm-a" class="antispam-control antispam-control-a" value="'.date('Y').'" /> <input type="text" name="antspm-q" class="antispam-control antispam-control-q" value="'.ANTISPAM_PLUGIN_VERSION.'" autocomplete="off" /> </p>
如果用户没有开启 JavaScirpt ,那么需要在这里情况内容,输入正确的答案。否者在后台就被判断是无效留言。
JS 自动回答答案
// 对表单答案添加答案,答案已经在 antispam-control-a 提供出来了。 elements = document.querySelectorAll('.antispam-control-q'); len = elements.length; for (i = 0; i < len; i++) { // set answer into other input instead of user elements[i].value = answer; } ... // 这里利用 JavaScript 添加一个动态的表单 // 如果没有开启 dynamic_control = document.createElement('input'); dynamic_control.setAttribute('type', 'hidden'); dynamic_control.setAttribute('name', 'antspm-d'); dynamic_control.setAttribute('class', 'antispam-control antispam-control-d'); dynamic_control.setAttribute('value', current_year); ... elements[i].appendChild(dynamic_control);
后台判断逻辑片段
if ( $antspm_q != date('Y') ) { // year-answer is wrong - it is spam if ( $antspm_d != date('Y') ) { // extra js-only check: there is no js added input - it is spam $spam_flag = true; if (empty($antspm_q)) { // empty answer - it is spam $antispam_error_message .= 'Error: empty answer. ['.esc_attr( $antspm_q ).']<br> '.$rn; } else { $antispam_error_message .= 'Error: answer is wrong. ['.esc_attr( $antspm_q ).']<br> '.$rn; } } }
如果用户没有启用 JavaScript 会怎么样呢?
用户会在提交表单中看到今天是公元多少年的问题,然后需要将错误的答案修改成正确的答案。这样在上面的后台检测脚本中就会发现,这里填写是正确的。就不用再关心 JavaScript 动态的答案了。
不可见的输入框陷阱 invisible input trap
不可见的输入框陷阱(invisible input trap)
是基于一个事实:大多数机器人遇到 email
或者 url
关键字表单会自动填充一些信息。
因此在评论框中增加一个隐藏字段,正常用户是看不到这个字段,所以也不会去填写它。
// 默认不展示给用户看。 <p class="antispam-group antispam-group-e" style="display: none;"> <label>Leave this field empty</label> <input type="text" name="antspm-e-email-url-website" class="antispam-control antispam-control-e" value="" autocomplete="off" /> </p>
但是机器人是可以看到这个字段的,如果在这里填写了任何东西,那么就会被判定为机器人。
后台的判断逻辑片段
// 如果填写了这个表单,那么就被判定是垃圾信息了 if ( ! empty($antspm_e)) { // trap field is not empty - it is spam $spam_flag = true; $antispam_error_message .= 'Error: field should be empty. ['.esc_attr( $antspm_e ).']<br> '.$rn; }
总结一下
目前从后台效果来看,这个插件的效果很好,很少遇到垃圾留言。
目前的一些垃圾机器人无法执行 JavaScript,所以很多利用这个特性就可以做一些排除了。很多的第三方评论都是利用 JS 展示出来了。
不过很优秀的 Disqus 在国内经常抽风,甚至不可用。
声明:未经允许禁止转载 东东东 陈煜东的博客 文章,谢谢。如经授权,转载请注明: 转载自东东东 陈煜东的博客
本文链接地址: 分享一个不用验证码的阻止垃圾机器人提交留言表单算法 – https://www.chenyudong.com/archives/anti-spam-comments-algorithm.html
发表评论