美文网首页有用收藏Web前端之路Hexo
Hexo折腾记之科学使用Disqus与Next的集成

Hexo折腾记之科学使用Disqus与Next的集成

作者: kmac007 | 来源:发表于2017-09-19 09:18 被阅读1990次

    本文首发于kmac007.me

    我可能就是个爱折腾的人吧。博客最早的时候部署在Github Pages,然而Github Pages实在太慢,而后迁到了Coding Pages。说实话,Coding Pages的访问速度非常快,实在是国内部署静态博客的利器。当然,你得在网站首页任意位置放置「Hosted by Coding Pages」的文字版或图片版来去除Pages跳转页。

    目前,我个人的博客kmac007.me已从Coding Pages迁移至个人租用的虚拟主机中。原因后面再说。

    Next主题的自定义

    Next这个主题真的是相当的棒,官方文档中有详细的说明,有多种主题可供选择,还集成了大量的第三方插件。

    而这个主题最吸引我的是简洁、优秀的代码高亮和显而易见的文章目录。但是原本的主题并不能并不能满足我的想法,因此我在Mist的基础上做了一些修改。(网上有很多Next主题的自定义教程,在此就不赘述了)

    预览地址:kmac007.me
    Github地址: https://github.com/kmac007/next-mist-kmac007

    科学使用Disqus

    如果不搭梯子disqus根本无法加载,一直处于加载中的状态,让人十分恼火。既然不搭梯子不能使用disqus,那么为什么还有用它呢?

    为什么使用disqus

    就当前的第三方评论工具中, 我对比了一下畅言、gitment、来必力。畅言需要备案才能使用,当然也可以用一些小技巧不备案也能使用畅言,畅言的问题是,不支持非登录用户评论,印象中评论期间好像还要关注公众号什么的,特别繁琐。gitment是一个基于GitHub Issues的评论系统,同样的不支持非登录用户评论,并且只支持github登录,还有一个问题是必须要初始化其他用户才可以发表评论。来必力,个人感觉并不好用,加载速度也不快,虽说支持github登录,但同样的并不支持非登录用户评论。

    而disqus支持未注册用户评论,但是头疼的是被墙的问题。直到我看到了这篇文章科学使用 Disqus,该文作者写了一个disqus-php-api,利用 PHP cURL 转发 Disqus API 请求。

    解决disqus被墙的问题

    具体简单的流程如下

    //伪代码
    if( Disqus正常访问 ) {
      客户端请求XHR -> Disqus响应 -> 结束
    }else if( Disqus被墙 ) {
      客户端请求XHR -> 服务端请求(cURL) -> Disqus响应 -> 服务端响应 -> 结束
    }
    

    具体实现细节请移步:科学使用 Disqusdisqus-php-api

    这个方案可以很好的解决Disqus被墙的问题,开始加载页面时,做一个判断,如果Disqus正常访问,则使用原生的Disqus评论;如果被墙则使用自制的评论框,使用Disqus API。

    因此要实现这个过程,我需要一个支持PHP的虚拟主机,这是我博客从Coding Pages迁出的原因。当然,其他方式也是可以的,这里我就不做深究了。

    disqus-php-api的配置

    这里参考了基于disqus-php-api在Hexo博客中使用Disqus

    搭建评论系统后端

    我的虚拟主机只支持FTP上传,而Hexo自动部署会报错,实在无法解决,只能通过FTP手动上传文件。

    获取disqus-php-api

    执行如下命令,将disqus-php-api拷贝到本地并重命名为disqus

    git clone https://github.com/fooleap/disqus-php-api disqus
    

    修改api目录下的config.php

    define('DISQUS_PUBKEY', 'E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F');
    define('DISQUS_USERNAME', 'your-username');
    define('DISQUS_EMAIL', 'your-email@qq.com');
    define('DISQUS_PASSWORD', 'your-disqus-password');
    define('DISQUS_WEBSITE', 'your-website');
    define('DISQUS_SHORTNAME', 'your-disqus-shortname');
    define('DISQUS_APPROVED', true);
    
    1. DISQUS_PUBKEY Disqus 公钥,无需修改
    2. DISQUS_USERNAME Disqus 用户名
    3. DISQUS_EMAIL Disqus 注册邮箱,重要
    4. DISQUS_PASSWORD Disqus 密码,重要
    5. DISQUS_WEBSITE 网站域名,如:'http://blog.fooleap.org'
    6. DISQUS_SHORTNAME 网站在 Disqus 对应的 Shortname
    7. DISQUS_APPROVED 评论是否免审核,true 即跳过评论预审核,false 则按后台设置

    这里要注意的是,DISQUS_PASSWORD选项中,域名不能这样写:‘https://kmac007.me/,域名后不能以'/'结尾,否则会出现一直创建Thread的情况

    上传到服务器

    由于我是FTP上传,直接通过FTP工具将整个disqus目录上传到网站的根目录中。

    disqus-php-api集成至hexo next

    修改Next的主题配置文件

    主题配置文件_config.yml中添加disqusapi相关参数

    如:

    # Disqus
    disqus:
      enable: false
      shortname: your-short-name
      count: false
    
    # Disqus APi
    disqusapi:
      enable: true
      forum: 'your-forum'
      site: 'your-site'
      api: 'https://yoursite.com/disqus/api'
      mode: 2
      badge: '博主'
      timeout: 3000
    
    • forum:DIsqus form的shortname
    • site:网站域名
    • api:PHP代码部署的网址:https://yoursite.com/disqus/api
    • mode
      • 1检测能否访问 Disqus,若能则加载 Disqus 原生评论框,超时则加载简易评论框
      • 2 仅加载简易评论框
      • 3 同时加载两种评论框,先显示简易评论框,Disqus 加载完成则切换至 Disqus 评论框
    • badge:管理员徽章文本
    • timeout:当mode为1时的超时时间

    添加disqusapi模块

    找到目录

    your-site/themes/next/layout/_third-party/comments/
    

    在其中新建名为disqusapi.swig文件,内容为:

    {% if theme.disqusapi.enable %}
        <link rel="stylesheet" href="/disqus/dist/iDisqus.min.css" />
        <script src="/disqus/dist/iDisqus.min.js"></script>
        <script>
            var emojiList = [{
                code:'smile',
                title:'笑脸',
                unicode:'1f604'
            },{
                code:'mask',
                title:'生病',
                unicode:'1f637'
            },{
                code:'joy',
                title:'破涕为笑',
                unicode:'1f602'
            },{
                code:'stuck_out_tongue_closed_eyes',
                title:'吐舌',
                unicode:'1f61d'
            },{
                code:'flushed',
                title:'脸红',
                unicode:'1f633'
            },{
                code:'scream',
                title:'恐惧',
                unicode:'1f631'
            },{
                code:'pensive',
                title:'失望',
                unicode:'1f614'
            },{
                code:'unamused',
                title:'无语',
                unicode:'1f612'
            },{
                code:'grin',
                title:'露齿笑',
                unicode:'1f601'
            },{
                code:'heart_eyes',
                title:'色',
                unicode:'1f60d'
            },{
                code:'sweat',
                title:'汗',
                unicode:'1f613'
            },{
                code:'smirk',
                title:'得意',
                unicode:'1f60f'
            }];
            var disq = new iDisqus('comments', {
                forum: '{{ theme.disqusapi.forum }}',
                site: '{{ theme.disqusapi.site }}',
                api: '{{ theme.disqusapi.api }}',
                mode: {{ theme.disqusapi.mode }},
                badge: '{{ theme.disqusapi.badge }}',
                timeout: {{ theme.disqusapi.timeout }},
                init: true,
                emoji_list: emojiList
            });
            disq.count();
        </script>
    {% endif %}
    

    引入index.swig

    在当前目录下的index.swig文件中添加:

    {% include 'disqusapi.swig' %}
    

    重新hexo g生成,再上传到服务器中即可看到disqus了。

    问题

    跨域

    你可能在控制台中出现这种问题。

    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    init.php文件中设置Access-Control-Allow-Origin部分:

    namespace Emojione;
    require_once('config.php');
    require_once('emojione/autoload.php');
    header('Content-type:text/json');
    $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
    if(preg_match('(localhost|127\.0\.0\.1|'.DISQUS_WEBSITE.')', $origin)){
        header('Access-Control-Allow-Origin: '.$origin);
    }
    $client = new Client(new Ruleset());
    

    删除原本设置 Access-Control-Allow-Origin 的代码,替换以下的代码:
    (其中,变量 allow_origin 是你要允许可以调用你后端的域名网址)

    namespace Emojione;
    require_once('config.php');
    require_once('emojione/autoload.php');
    header('Content-type:text/json');
    //跨域访问的时候才会存在此字段
    $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
    
    $allow_origin = array(
        'http://smk17.cn',
        'http://www.smk17.cn'
    );
    
    if(in_array($origin, $allow_origin)){
        header('Access-Control-Allow-Origin:'.$origin);
    }
    $client = new Client(new Ruleset());
    

    创建thread

    如果出现创建thread的问题,那么可以通过 mode选择1,再翻墙访问你的文章页面,这时候加载原生Disqus评论系统,thread就创建成功了。

    特别要注意的是:如果你的文章标题中带有中文,会无法创建thread,所以不要使用中文命名文章。

    本文参考了fooleapSengMitnick的工作,非常感谢两位的工作。

    参考

    1. 科学使用 Disqus
    2. 基于disqus-php-api在Hexo博客中使用Disqus

    相关文章

      网友评论

      • fd7926b4044a:已经在用了!!!谢谢!!!地址:http://lao47.xin
      • 8b806cd07e2c:上传到服务器
        由于我是FTP上传,直接通过FTP工具将整个disqus目录上传到网站的根目录中。
        将disqus目录上传到GitHub中和这一段的意思一样吗?

      本文标题:Hexo折腾记之科学使用Disqus与Next的集成

      本文链接:https://www.haomeiwen.com/subject/yhtwsxtx.html