Giter Site home page Giter Site logo

sukkaw / disqusjs Goto Github PK

View Code? Open in Web Editor NEW
634.0 9.0 55.0 421 KB

:speech_balloon: Render Disqus comments in Mainland China using Disqus API

Home Page: https://disqusjs.skk.moe

License: MIT License

JavaScript 3.27% HTML 10.10% TypeScript 73.35% Sass 13.28%
disqus disqus-api javascript hexo hugo disqusjs disqusjs-disqus react react-component

disqusjs's Introduction

DisqusJS

https://disqusjs.skk.moe

纯前端、超轻量级的「评论基础模式」实现:使用 Disqus API 渲染评论列表

npm version Author npm license jsDelivr Hits

简介

DisqusJS 是一个基于 Disqus API 和 React 开发的 Embed 插件。DisqusJS 通过 Disqus API 渲染只读的评论列表,搭配反向代理可以实现在网络审查地区加载 Disqus 评论列表;支持自动检测访客是否能够访问 Disqus、并自动选择加载原生 Disqus(评论完整模式)或 DisqusJS 提供的评论基础模式。

功能

  • 判断访客能否访问 Disqus、自动选择「评论基础模式」或「Disqus 完整模式」
  • 展示评论列表、支持按照「最新」、「最早」、「最佳」排序
  • 可搭配 React(Gatsby、Next.js)使用

Demo

安装和使用

在 HTML 中直接引入

在你需要安装 DisqusJS 的页面的 </head> 之前引入 DisqusJS 的 CSS:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/styles/disqusjs.css">

在需要展示评论的地方插入 JS:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/disqusjs.es2015.umd.min.js"></script>

<!-- 如果你只兼容现代浏览器,你也可以使用 ES Module -->
<script type="module">
  import DisqusJS from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/disqusjs.es2018.es.min.mjs'
</script>

接着创建一个 DisqusJS 容器:

<div id="disqusjs"></div>

通过 NPM 安装

npm i disqusjs
# Yarn
# yarn add disqusjs
# pnpm
# pnpm add disqusjs

然后在项目中引入 DisqusJS:

// CommonJS
const DisqusJS = require('disqusjs/dist/disqusjs.es2015.umd');
// const DisqusJS = require('disqusjs/dist/disqusjs.es2017.umd');
// const DisqusJS = require('disqusjs/dist/disqusjs.es2022.umd');

// ES Module
import DisqusJS from 'disqusjs/dist/disqusjs.es2015.es.js';
// import DisqusJS from 'disqusjs/dist/disqusjs.es2017.es.js';
// import DisqusJS from 'disqusjs/dist/disqusjs.es2022.es.js';

注意,你仍然需要手动引入 DisqusJS 的 CSS:

import 'disqusjs/dist/styles/disqusjs.css';

使用下述代码初始化一个 DisqusJS 实例。注意初始化需在 DisqusJS 加载完成后进行:

const disqusjs = new DisqusJS({
    shortname: '',
    siteName: '',
    identifier: '',
    url: '',
    title: '',
    api: '',
    apikey: '',
    admin: '',
    adminLabel: ''
});

接下来,我们需要让 DisqusJS 实例将评论组件渲染到页面上:

disqusjs.render(document.getElementById('disqusjs'));
// 你也可以传入一个 CSS 选择器
// disqusjs.render('#disqusjs');

作为 React 组件使用

import 'disqusjs/dist/react/styles/disqusjs.css';
import { DisqusJS } from 'disqusjs/dist/react/disqusjs.es2015.es.js';
// import { DisqusJS } from 'disqusjs/dist/react/disqusjs.es2017.es.js';
// import { DisqusJS } from 'disqusjs/dist/react/disqusjs.es2022.es.js';
// const { DisqusJS } = require('disqusjs/dist/react/disqusjs.es2015.umd');
// const { DisqusJS } = require('disqusjs/dist/react/disqusjs.es2017.umd');
// const { DisqusJS } = require('disqusjs/dist/react/disqusjs.es2022.umd');

<DisqusJS
  shortname=""
  siteName=""
  identifier=""
  url=""
  api=""
  apikey=""
  admin=""
  adminLabel=""
/>

完成上述步骤后,DisqusJS 就已经在您的站点安装好了,但是你现在还不能使用它。要使用 DisqusJS,你还需要进行一些配置。

配置 Disqus Application

Disqus API Application 处注册一个 Application。

点击新创建的 Application,获取你的 API Key(公钥)。

在 Application 的 Settings 页面设置你使用 DisqusJS 时的域名。Disqus API 会检查 API 请求的 Referrer 和 Origin。

配置 DisqusJS 参数

shortname {string}

siteName {string}

identifier {string}

  • 当前页面的 identifier,用来区分不同页面
  • 建议,默认值为 document.location.origin + document.location.pathname + document.location.search

url {string}

  • 当前页面的 URL,Disqus 的爬虫会爬取该 URL 获取页面相关信息
  • 建议,默认值为 document.location.origin + document.location.pathname + document.location.search

title {string}

  • 当前页面的标题,如果没有设置默认为当前页面的标题。当页面标题中有其他信息(比如站点名称)而不想在 Disqus 中展示时,可以设置此项。
  • 非必须,默认值为 document.title

api {string}

  • DisqusJS 请求的 API Endpoint,通常情况下你应该配置一个 Disqus API 的反代并填入反代的地址。你也可以直接使用 DISQUS 官方 API 的 Endpoint https://disqus.com/api/,或是使用我搭建的 Disqus API 反代 Endpoint https://disqus.skk.moe/disqus/。如有必要可以阅读关于搭建反代的 相关内容
  • 建议,默认值为 https://disqus.skk.moe/disqus/

apikey {string | string[]}

  • DisqusJS 向 API 发起请求时使用的 API Key,你应该在配置 Disqus Application 时获取了 API Key
  • DisqusJS 支持填入一个 包含多个 API Key 的数组,每次请求时会随机使用其中一个;如果你只填入一个 API Key,可以填入 string 或 Array。
  • 必填,无默认值

nesting {number}

  • 最大评论嵌套数;超过嵌套层数的评论,会不论从属关系显示在同一层级下
  • 非必须,默认值为 4

nocomment {string}

  • 没有评论时的提示语(对应 Disqus Admin - Settings - Community - Comment Count Link - Zero comments)
  • 非必须,默认值为 这里冷冷清清的,一条评论都没有

以下配置和 Disqus Moderator Badge 相关,缺少一个都不会显示 Badge

admin {string}

adminLabel {string}

SPA 与 PJAX 站点注意事项

如果你在 React SPA、Next.js、Gatsby 中以 React 组件的形式使用 DisqusJS,无需任何额外步骤,只需修改 <DisqusJS /> 组件的 prop,DisqusJS 会自动更新。

如果你在 PJAX 站点中使用,需要在页面 unload 之前手动销毁 DisqusJS 实例,并新页面 load 后重新渲染一个 DisqusJS 实例:

let disqusjs = null;
// 初始化 DisqusJS 实例
disqusjs = new DisqusJS({
  // ...
});
// 将 DisqusJS 渲染到页面上
disqusjs.render(document.getElementById('disqusjs'));

document.addEventListener('pjax:send', () => {
  // 销毁 DisqusJS 实例
  disqusjs.destroy();
});

document.addEventListener('pjax:complete', () => {
  // 使用新的参数(如新的 identifier 和 url)创建全新的 DisqusJS 实例
  disqusjs = new DisqusJS({
    // ...
  });
  // 渲染新的 DisqusJS
  disqusjs.render(document.getElementById('disqusjs'));
});

如何搭建 Disqus API 反代

使用 Caddy 或者 Nginx 都可以搭建一个反代服务器,需要反代的 Endpoint 是 https://disqus.com/api/。这里介绍的是针对不使用服务器和后端程序,使用 Serverless 平台搭建 Disqus API 反代的方法。

Vercel

Vercel 是一个 Serverless 平台。免费的 Hobby Plan 提供每月 100 GiB 流量和无限的请求次数。 sukkaw/disqusjs-proxy-example 提供了一个使用 Now Router 进行反代的样例配置文件。

Cloudflare Workers

Cloudflare Workers 提供了一个在 Cloudflare 上运行 JavaScript 的平台。免费 Plan 可提供每天 100000 次免费请求次数额度。 idawnlight/disqusjs-proxy-cloudflare-workers 提供了一份使用 Cloudflare Workers 进行反代的样例代码。

Firebase

Firebase Cloud Functions 提供了执行 Node.js 代码的 Serverless 平台。需绑定银行卡 (Visa 或 MasterCard) 才能启用互联网出站访问功能。 ysc3839/disqusjs-proxy 的 firebase 分支 提供了一个可以部署在 Firebase 上的反代样例。

注意事项

  • Disqus API 不支持通过 AJAX 方式调用创建评论或者初始化页面,所以自动初始化页面和创建匿名评论在不搭配专门的后端程序的话不能实现。
    • Disqus API 会检查请求是否包含 OriginX-Request-With 等响应头、拦截 AJAX 请求。就算 Disqus API 不做检查,把你的私钥和公钥一起明文写在前端也是 十分愚蠢
  • 所以如果 DisqusJS 检测到当前页面没有初始化、会提示是否切换到 Disqus 完整模式进行初始化。
  • DisqusJS 仅在当前域名首次访问时检测 Disqus 可用性并选择模式,并把结果持久化在 localStorage 中,之后访问都会沿用之前的模式。
  • 一个 Disqus Application 的 Rate Limit 是每小时 1000 次;DisqusJS 一次正常加载会产生 2 次请求。DisqusJS 支持将多个 API Key 填入一个 Array 中,并在请求时随机选择(负载均衡)。你可以创建多个 Disqus API Application 并分别获取 API Key。

从 DisqusJS 1.3.0 升级到 DisqusJS 3.0.0

<!-- 替换 DisqusJS 版本 -->
<!--<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/disqusjs.css">-->
<!--<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/disqus.js"></script>-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/styles/disqusjs.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser/disqusjs.es2015.umd.min.js"></script>

<!--
  DisqusJS 1.3.0 容器的 id 属性必须是 `disqus_thread`,
  DisqusJS 3.0.0 容器的 id 属性 **必须不是** `disqus_thread`。
  建议使用 "disqusjs" 作为 DisqusJS 容器的 id 属性。
-->
<!--<div id="disqus_thread"></div>-->
<div id="disqusjs"></div>
<script>
  const disqusjs = new DisqusJS({
    // DisqusJS 1.3.0 和 DisqusJS 3.0.0 配置完全兼容,无需更改
    // ...
  });

  // DisqusJS 1.3.0 在初始化实例后评论列表已经开始渲染到页面上,DisqusJS 3.0.0 还需要额外调用 render() 方法:
  disqusjs.render(document.getElementById('disqusjs')); // render() 方法需要传入 DisqusJS 的容器

  // DisqusJS 3.0.0 新增了销毁实例的 destroy() 方法,你可以在 PJAX 跳转时直接调用它:
  disqusjs.destroy();
  // 关于 PJAX 站点使用,请参考前文「SPA 与 PJAX 站点注意事项」
</script>

谁在使用 DisqusJS?

如果你的站点或者个人博客在使用 DisqusJS,来 把你的网站分享给其他人吧

Author 作者

DisqusJS © Sukka, Released under the MIT License.
Authored and maintained by Sukka with help from contributors (list).

Personal Website · Blog · GitHub @SukkaW · Telegram Channel @SukkaChannel · Mastodon @[email protected] · Twitter @isukkaw · Keybase @sukka

disqusjs's People

Contributors

nonzzz avatar paiji avatar renbaoshuo avatar sukkaw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

disqusjs's Issues

自定义 url 无效的问题

image

比如说这样子设置的,但是不知道为什么disqus_config像是没生效一样,实在不知道为啥啊,disqus的文档里也是这样写的,可是就是没生效。

发生在本地测试的时候

使用listPostsThreaded API有较大的延迟

相比起listPosts.json API,使用listPostsThreaded我碰到的一个问题是,在新的评论发表后,该API需要过一段时间(大概半个小时)才能获得新评论,如下图,虽然已经可以用API列出评论数,但是新的评论不会被listPostsThreaded立刻获得。
屏幕快照 2020-07-26 01 33 23
可以使用curl测试这两个API的行为。
虽然影响也不大,但是还是让人有一些遗憾。不知道是否有解决方法。

main 方法执行时机问题

博客实际使用过程中,部分地区加载 google analytics 有问题,导致 window.onload 事件过很久才会触发,这时候评论一直是空白状态

不知道把 main 方法放在 window.onload 执行的考虑是什么?

无评论时无法切换到 Disqus

无评论时点击「尝试完整 Disqus 模式」和「强制完整 Disqus 模式」均无效,但是加载失败时点「重试」是有效的,有评论时无此问题

Chrome 与 Firefox 均成功复现

bug

Remove AMD?

As this article said,

AMD is no longer a popular format, making it a likely distant fourth contender to ES Modules, CommonJS and globals. The problems AMD solves have been moved elsewhere - typically into the realm of module bundlers like Webpack and Rollup. Instead of asynchronous loading as a feature of our chosen module formats, it's an implementation detail of our chosen bundler.

We can remove AMD to save bytes as the article mentioned.

function DisqusJS(config) {}
// attempt to export for CommonJS
try { module.exports = DisqusJS; } catch (e) {}  

Thread初始化失败

2019-10-19_205937
你好,当时按照文档描述的diygod大佬升级disqus方法进行操作,发现会出现这种情况,请问这是怎么回事呢?有的过一段时间又可以了。

建议在fetch前对GET参数进行encodeURIComponent

经过测试,fetch自动对unicode字符如中文进行utf8 encode。但是在IE浏览器上,没有fetch,而替代的行为则不是使用utf8 encode,导致了GET的参数编码不一致。
如果要重现这一行为,可以分别使用任意系统的非IE浏览器与IE浏览器访问该网页,并使用开发者工具查看list.json请求的request header,IE浏览器的请求头编码是不同的。
经过测试,disqus API的服务器会使用与decodeURIComponent一致的行为对GET参数进行解码,故先对参数进行encodeURIComponent可以在保持向后兼容的同时也对不同浏览器行为保持一致。

Disqus本身存在问题

看到博主关于disqusjs的博客很喜欢,就在下面评论了很长,然后今天发现被无脑标注spam了,不知道是博主设置的原因还是disqus的原因?
image

我刚还以为是博主自己不喜欢我的评论,就再发了一条询问,结果刚评论重新刷新就被分为spam了。应该是disqus判定的。
更加厌恶disqus了。

dark mode support

Do you have plan to support dark mode?

@media (prefers-color-scheme: dark) {
}

CROS 问题

image

image

image

image

请问大佬有没有什么解决办法?

按照教程设置好DisqusJS,但是基础模式加载失败

NexT主题7.8.0,disqusJS的版本是1.3.0。
开启了pjax。
评论基础模式加载失败,完全模式能够正常使用。
通过SwitchOmega查看,发现网页的来自.sukk.moe域名的资源无法加载。
尝试false那个pjax也无法解决,api已经填写推荐的反代网址,密钥什么的都检查过了。尽力了…
请问这个该如何解决?
谢谢!

The issue of basic comment pattern

The cloud server of Chinese mainland ask me to register from Chinese network police station, so I use IP address long time because I think it is unsafe. I found if I use the IP Address as Disqus's "Domain", the comment will not appear with "basic comment pattern"(unless homepage). If I choose "Full Pattern", the comment will appear.

e.g. When I visit http://81.68.192.120, I found the request contains "list.json?" and "listPostsThreaded?". But when I choose to visit http://81.68.192.120/public/blog/137, the request just contains "list.json?". So the function of basic comment pattern would disabled.

当使用pjax时,disqusjs显示异常

直接打开文章
很明显,disqus正常工作了
但是如果从首页中打开这篇文章,会造成这样的效果
image
APlayer有类似的问题,但可以通过pjax刷新时回调
if (typeof aplayers !== 'undefined'){ for (var i = 0; i < aplayers.length; i++) { try {aplayers[i].destroy()} catch(e){} } } loadMeting();
解决,不知道disqusjs该如何正常回调,或是增加原生pjax支持?

InstantClick下异常

问题和 #14 这里的截图完全一样。

当页面内通过InstantClick刷新时,评论会正常显示。但那个“加载中..."的一大串提示不会自动消失。按F5刷新都是正常的。

跟随深色模式切换

当 DisqusJS 加载完以后,切换网站的深色(或浅色)样式,评论样式不能跟随适配。我发现我也提过这样的 Issue,现在解决了,分享一下。每个网站切换深色模式的方法不一样,所以感觉不太适合提 PR。

  1. 监听样式切换事件
let event = new Event('themeChanged');
document.dispatchEvent(event);
  1. 重载 DisqusJS
<script>
    var disqus_config = function () {
        this.page.url = ' '; // Replace PAGE_URL with your page's canonical URL variable
        this.page.identifier = ' '; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
    };

    (function () {
        var d = document,
            s = d.createElement('script');
        s.src = 'https://eallion.disqus.com/embed.js'; // Replace SITE_URL with your site's URL
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();

    // Disqus theme switching
    document.addEventListener('themeChanged', function (e) {
        if (document.readyState == 'complete') {
            DISQUS.reset({
                reload: true,
                config: disqus_config
            });
        }
    });
</script>

ref: https://help.disqus.com/en/articles/1717163-using-disqus-on-ajax-sites

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.