对于博客内容加密这件事,在有后端服务器的情况下,是一件比较简单的事情,但是对于静态博客来说,就比较麻烦了。Hexo 博客里面有个非常著名的加密插件 hexo-blog-encrypt,它的大概原理是在 hexo g 的时候对 HTML 的内容进行加密,然后在输入正确的密码后解密出正确的 HTML 内容。

在插件的 issue 列表里面一个 Won’t fix 的 issue 里面提到一个问题是这个插件解密后导致 Dplayer 播放器显示不出来。

https://github.com/D0n9X1n/hexo-blog-encrypt/issues/190

最后的结论是受限于 Hexo 静态博客的特性,这个问题不会被修复。

Encrypting blog content is a fairly simple task when you have a backend server, but for static blogs it’s much more troublesome. There’s a very famous encryption plugin for Hexo blogs, hexo-blog-encrypt. Its rough principle: it encrypts the HTML content during hexo g, then decrypts it to reveal the correct HTML after the correct password is entered.

In the plugin’s issue tracker, a Won’t fix issue mentions that after decryption, the Dplayer player fails to display.

https://github.com/D0n9X1n/hexo-blog-encrypt/issues/190

The final conclusion was that, due to the nature of Hexo static blogs, this issue will not be fixed.

类似地,这个问题在 hexo-tag-dplayerhexo-tag-aplayer 的 issue 里面也有提到。

https://github.com/MoePlayer/hexo-tag-dplayer/issues/26

https://github.com/MoePlayer/hexo-tag-aplayer/issues/124

就是这样一个冲突了好几年的问题,竟然在抄来抄去的中文互联网里面没有找到一个 Step by Step 的解决方案,为数不多的线索就是需要用回调函数,但是具体怎么用,没有一个详细的说明。

问题定位

从控制台的报错信息来看,写的是 Dplayer 未定义,在我的博客文章中的 new DPlayer 代码执行错误。

再结合这些插件的 issue 列表,这个错误表明 Dplayer 或者 Aplayer 的 JS 文件没有被正确加载。

解决方案

再进一步观察控制台的输出,发现 JS 的加载实际上在解密出来的 new DPlayer 执行之后才被执行。

所以我的解决思路就是在解密之前就加载 Dplayer 或者 Aplayer 的 JS 文件

hexo-blog-encrypt 插件的解密函数是 decrypt,它被写在了 lib/hbe.js 里面。

所以我要做的是在 hbe.js 里面引入 Dplayer 或者 Aplayer 的 JS 文件,然后在解密之前就加载这个 JS 文件。

具体步骤如下:

  1. fork hexo-blog-encrypt 仓库

  2. 修改 lib/hbe.js 文件,加入 Dplayer 或者 Aplayer 的 JS 文件在 hbe.js 文件的头部

1
2
3
4
5
6
7
8
9
10
11
var dpjs = document.createElement('script');
dpjs.src = 'https://npm.elemecdn.com/dplayer/dist/DPlayer.min.js';
document.head.appendChild(dpjs);

var apjs = document.createElement('script');
apjs.src = 'https://npm.elemecdn.com/aplayer/dist/APlayer.min.js';
document.head.appendChild(apjs);

var mtjs = document.createElement('script');
mtjs.src = 'https://npm.elemecdn.com/meting/dist/Meting.min.js';
document.head.appendChild(mtjs);

  1. 修改 package.json 文件,改为使用我们自己的仓库

格式为: github:用户名/仓库名

1
"hexo-blog-encrypt": "github:WANG-Guangxin/hexo-blog-encrypt",

当然,你也可以自己做个 npm 的包。

  1. 重新安装 hexo-blog-encrypt 插件
1
npm install hexo-blog-encrypt --save

再次部署博客,问题解决。

Similarly, this problem is also mentioned in the issues of hexo-tag-dplayer and hexo-tag-aplayer.

https://github.com/MoePlayer/hexo-tag-dplayer/issues/26

https://github.com/MoePlayer/hexo-tag-aplayer/issues/124

A problem that has been around for years, yet in the Chinese internet full of copy-pasted content, I couldn’t find a single step-by-step solution. The few clues that existed all said you need a callback function, but none explained exactly how to use it.

Locating the problem

From the console error messages, it says Dplayer is undefined — the new DPlayer code in my post failed to execute.

Combined with the issue trackers of these plugins, this error indicates that the Dplayer or Aplayer JS files were not loaded properly.

The solution

Looking closer at the console output, the JS loading actually happens after the decrypted new DPlayer executes.

So my approach was: load the Dplayer or Aplayer JS file before decryption.

The decrypt function of hexo-blog-encrypt is called decrypt, written in lib/hbe.js.

So what I need to do is import the Dplayer or Aplayer JS file in hbe.js, and load it before decryption.

The specific steps:

  1. Fork the hexo-blog-encrypt repository

  2. Modify lib/hbe.js — add the Dplayer or Aplayer JS files at the top of the hbe.js file

1
2
3
4
5
6
7
8
9
10
11
var dpjs = document.createElement('script');
dpjs.src = 'https://npm.elemecdn.com/dplayer/dist/DPlayer.min.js';
document.head.appendChild(dpjs);

var apjs = document.createElement('script');
apjs.src = 'https://npm.elemecdn.com/aplayer/dist/APlayer.min.js';
document.head.appendChild(apjs);

var mtjs = document.createElement('script');
mtjs.src = 'https://npm.elemecdn.com/meting/dist/Meting.min.js';
document.head.appendChild(mtjs);

  1. Modify package.json to use your own repository

Format: github:username/repository

1
"hexo-blog-encrypt": "github:WANG-Guangxin/hexo-blog-encrypt",

Of course, you could also publish your own npm package.

  1. Reinstall the hexo-blog-encrypt plugin
1
npm install hexo-blog-encrypt --save

Deploy the blog again and the problem is solved.