环境

  • Typecho开源博客
  • Handsome主题(本文的第二个问题不知道是否跟主题有关,如果你没有使用这个主题那么本文的第二个修改并不完全适用你,不过可以作为参考,在其他主题下修改也是类似的)
  • Captcha验证码插件

Handsome主题下载,官网(收费)

https://www.ihewro.com/archives/489/

Captcha验证码插件下载地址

百度网盘: https://pan.baidu.com/s/1_dVLVoeKoefbxKGpXODnxg 提取码: xfnk

安装

  • 首先下载 Captcha 插件,将其上传至 typecho 的 /usr/plugins/ 目录下
  • 登陆博客后台,在控制台的插件项中中启用 Captcha 插件
  • 编辑博客当前使用的主题模板中的comments.php文件,在评论的表单位置也就是comments的form标签之间的任何你认为合适的地方,加上如下代码:
    <p><?php Captcha_Plugin::output(); ?></p>

注意:如果你使用了handsome主题,那么应该修改这个文件:

/usr/themes/handsome/component/comments.php

  • 保存文件,刷新网站即可看到效果。
    FireShot Capture 004 - 推荐一款适用于 Typecho 的评论验证码插件 - 向晚时光 - www.timelate.com.png

问题

启用这个插件貌似一切顺利,手机端也可以正常使用。可惜并不完美符合我的要求,有两个问题。

  1. 输入一次验证码成功评论之后typecho会刷新页面显示新评论。此时验证码图片并没有刷新,可是如果继续评论,输入同样的验证码会提示评论失败,此时只有手动F5刷新整个页面才会刷新正确的验证码。
  2. 输入错误的验证码只会提示评论不符合要求这个错误,并没有提示验证码错误。而且验证码区域并不会自动刷新,对用户不友好,用户不知道哪里出问题了。
  3. 默认的6个字符对用户不友好,我觉得2个字符足够挡住绝大多数的垃圾评论了。所以字符数要改成2。

修改

  1. 添加一个刷新按钮,让用户可以手动刷新验证码。
    文件:/usr/plugins/Captcha/Plugin.php

修改output函数如下:

public static function output()
{
    echo '为防止恶意评论,评论前请输入下面图形中的两位英数字<br><img id="captchapic" src="' . Typecho_Common::url('/action/captcha', Helper::options()->index) 
    . '" title="' . _t('请点击按钮刷新验证码,点击图片刷新无效') . '" /><br />'
    . '<input type="text" class="captcha" name="captcha" />  '
    . '<input id="btnUpdCaptcha" type="button" onclick="document.getElementById(\'captchapic\').src = document.getElementById(\'captchapic\').src + \'?\' + Math.random()" value="刷新验证码"></input>';
}
  1. 修改hansome主题的js文件,实现提交评论后自动刷新验证码。不论有没有成功。
    文件:/usr/themes/handsome/assets/js/core.min.js

这里需要先将这个js文件格式化一下,因为作者已经用js混淆器给源代码js处理过,直接打开是天书。格式化方法很多就不介绍了。我使用的方法是使用vscode里面的一个格式化插件。
格式化以后,找到下面这句代码
if (!a(".comment-list", k).length)
找到以后在这句话的前后修改成以下代码:

For handsome主题 5.3.1

// Added by mango
// 提交评论后,不论成功与否,自动刷新验证码
// 判断是否使用了验证码插件,如果有则自动刷新验证码
// 这个btnUpdCaptcha需要跟插件里定义的刷新验证码按钮id一致
if (a("#btnUpdCaptcha")) {
    // 调用刷新验证码按钮的onclick事件
    a("#btnUpdCaptcha").click();
}
// 下面这句话判断评论是否成功,如果失败了才进入里面的逻辑
if (!a(".comment-list", k).length) {

    // Added by mango
    // 这里的a就是jquery,作者做了混淆
    // 判断k有没有包含错误消息,如果有则弹出这个错误消息
    // 目前知道的是插件在抛出Typecho_Widget_Exception异常带上的错误消息会以下面这种形式输出
    // <div class="container">
    //   Typecho_Widget_Exception异常带上的错误消息
    // </div>
    //debugger
    if (!a(".container", k).length) {
        // 进入到这里表示因为某种原因评论不成功
        return (
            a.message({
                title: LocalConst.COMMENT_TITLE,
                message: a.trim(a.parseHTML(k)[7].innerText),  // [7]目前还没找到好办法,强行取k这个页面的第7个元素,本来应该根据class取的
                type: "error",
            }),
            a(h).removeClass("active"),
            a("#spin").removeClass("show inline"),
            c("#error"),
            !1
        );
    } else {
        // 如果没找到则返回handsome标准错误信息
        return (
            a.message({
                title: LocalConst.COMMENT_TITLE,
                message: LocalConst.COMMENT_CONTENT_LEGAL_INFO,
                type: "error",
            }),
            a(h).removeClass("active"),
            a("#spin").removeClass("show inline"),
            c("#error"),
            !1
        );
    }
}

For handsome主题 6.0

// Added by mango
// 提交评论后,不论成功与否,自动刷新验证码
// 判断是否使用了验证码插件,如果有则自动刷新验证码
// 这个btnUpdCaptcha需要跟插件里定义的刷新验证码按钮id一致
if (a("#btnUpdCaptcha")) {
    // 调用刷新验证码按钮的onclick事件
    a("#btnUpdCaptcha").click();
}
// 下面这句话判断评论是否成功,如果失败了才进入里面的逻辑
if (!a(".comment-list", k).length) {

    // Added by mango
    // 这里的a就是jquery,作者做了混淆
    // 判断k有没有包含错误消息,如果有则弹出这个错误消息
    // 目前知道的是插件在抛出Typecho_Widget_Exception异常带上的错误消息会以下面这种形式输出
    // <div class="container">
    //   Typecho_Widget_Exception异常带上的错误消息
    // </div>
    //debugger
    if (!a(".container", k).length) {
        // 进入到这里表示因为某种原因评论不成功
        return (
            console.log(a("div", k)),
            ("undefined" != typeof content && "" != content) ||
                (content = LocalConst.COMMENT_CONTENT_LEGAL_INFO),
            a.message({
                title: LocalConst.COMMENT_TITLE,
                message: a.trim(a.parseHTML(k)[7].innerText),  // [7]目前还没找到好办法,强行取k这个页面的第7个元素,本来应该根据class取的
                type: "error",
            }),
            a(h).removeClass("active"),
            a("#spin").removeClass("show inline"),
            c("#error"),
            !1
            );

    } else {
        // 如果没找到则返回handsome标准错误信息
        return (
            console.log(a("div", k)),
            ("undefined" != typeof content && "" != content) ||
                (content = LocalConst.COMMENT_CONTENT_LEGAL_INFO),
            a.message({
                title: LocalConst.COMMENT_TITLE,
                message: content,
                type: "error",
            }),
            a(h).removeClass("active"),
            a("#spin").removeClass("show inline"),
            c("#error"),
            !1
            );
    }
}
  1. 把验证码字符的个数从默认的6个改成2个。
    文件:/usr/plugins/Captcha/securimage2/securimage.php

找到$this->code_length = 6;,改成2即可。

完成效果

  • 提供手动更新验证码按钮
  • 提交成功后自动刷新验证码
  • 没有输入或者输入错误会有错误提示并同时自动刷新验证码
  • 只要求输入2个字符
    FireShot Capture 005 - 解决不能访问json文件的一种方法 - 芒果爱吃胡萝卜 - blog.mangolovecarrot.net.png

版权属于:芒果爱吃胡萝卜

本文链接:http://blog.mangolovecarrot.net/2020/06/23/122

转载时须注明出处及本声明

Last modification:June 29th, 2020 at 05:43 am