导语

这周的某一天看 如何选择适合的公共 DNS | Sukka’s Blog 这篇博文,看到 兽兽大佬的 dns.sb 那段:

此外,有 VPS 的可以试试 trace 一下 185.222.222.222、没准你会发现你的 VPS 和 dns.sb 在同一内网里。

于是,我就准备到 azure 上试试,至少 az 应该有节点吧


???
怎么还多了条小尾巴

故事就从这条版权小尾巴开始吧

之前我发现我的一篇博文被 csdn 转走了,没有注明来源就算了,偷了文章格式也是乱七八糟,但是标题又是有“转载”字样,我推测是 csdn 有个什么一键转载的按钮。于是在文章末尾加了版权的说明文字,下文等会儿会说,但是他这个复制粘贴加小尾巴的功能,比文章末尾的说明文字要”恶心”点,因为很多人是无视说明文字的,但是小尾巴从粘贴的时候就被带出来,容易引起注意一点吧。

于是我决定排查一下,我也加上(呲牙)

排查小尾巴

我们需要找到添加小尾巴的js代码,其实我最开始是直接在源代码中找js标签,后来发现有个更简单的方法。

  1. 使用 Chrome 打开网页
  2. F12 呼出开发者工具
  3. 在 Elements 标签页中,右边有个 Event Listeners(事件监听器)
  4. 然后我们拷贝的动作是 copy,点开就可以看到是这个cp.js在作祟了。

内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
!function() {
function a(a) {
var b, c;
if (a.preventDefault(),
b = window.getSelection().toString() + "<br><br>本文采用 CC BY-NC-SA 4.0 许可协议,著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。<br>作者:Sukka<br>来源:" + document.title + "<br>链接:" + window.location.href,
c = window.getSelection().toString() + "\n\n本文采用 CC BY-NC-SA 4.0 许可协议,著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。\n作者:Sukka\n来源:" + document.title + "\n链接:" + window.location.href,
a.clipboardData)
a.clipboardData.setData("text/html", b),
a.clipboardData.setData("text/plain", c);
else if (window.clipboardData)
return window.clipboardData.setData("text", c)
}
document.body.addEventListener("copy", function(b) {
window.getSelection().toString().length > 10 && a(b)
})
}();

这样就很清晰了。
当触发copy事件时,如果选中的内容长度大于10,就会在选中内容末尾增加小尾巴。但是这个条件比较宽松,随便复制个ip地址,都要给我加个小尾巴。

但是我还注意到另外一个问题,就是这个js的地址,是

1
https://shadow.elemecdn.com/npm/[email protected]/js/cp.js

怎么能够把自己的js文件传到饿了么的cdn上呢?
实际上,苏卡卡是发布了一个npm包,叫skx,这个cp.js是里面的一个文件。

通过一番搜索,发现

  1. 苏卡卡曾在部分 CDN 厂商海外节点记录一贴中,将shadow.elemecdn.com作为测试域名,饿了么cdn上游用的阿里云CDN。并且直接访问shadow.elemecdn.com会提示如下,也能看出是aliyun

    1
    2
    3
    4
    AccessDenied
    The bucket you visit is not belong to you.
    5CA62B4DE15FB32EA29B73DE
    faas-resource.oss-cn-shanghai.aliyuncs.com
  2. 从v站另一贴貌似发现了一个 unpkg.com 在国内的镜像?中,neo曾提到

    我自己私底下都用饿了么的 npm.elemecdn.com 和 github.elemecdn.com

因为文中提到jsDelivr,虽然没有看到明确的说法,我还是作出推测,elemecdn可能是和jsDelivr淘宝npm镜像,和官方服务器全量同步。

jsDelivr
官网:https://www.jsdelivr.com/
苏卡卡dalao的博客也有其详细评测
开源的CDN,主要赞助商:

  • Cloudflare(Cloudflare Business Plan)
  • fastly
    官方的介绍明确写到
    1
    2
    // load any project hosted on npm
    https://cdn.jsdelivr.net/npm/package@version/file

全量同步,我测试了一下。
在npmjs上搜索skx时,还有另外一个不是苏卡卡写的包

1
https://www.npmjs.com/package/skx-base

version:1.0.1

jsDelivr的地址:

1
https://cdn.jsdelivr.net/npm/[email protected]/index.js

npm.elemecdn.com:

1
http://npm.elemecdn.com/[email protected]/index.js

shadow.elemecdn.com:

1
http://shadow.elemecdn.com/npm/[email protected]/index.js

内容都是一样的。

给 hexo 添加版权小尾巴

终于可以说本文的主题了,如果算上粘贴时添加小尾巴,那么就有两种方式了

  1. 在文章末尾添加版权小尾巴

这是最基础的方式。
使用大部分 hexo 应该都有的一个配置项,postMessage,再配合 hexo 内置的变量来添加地址,我的如下

1
postMessage:  您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。  <br/>本文作者:<a href="<%- url_for(config.url) %>">驱蚊器喵</a><br/>本文链接:<a href="<%- url_for(page.permalink) %>"><%- url_for(page.permalink) %> </a><br/>本文采用 <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0 Unported</a> 协议进行许可,请阅读 相关说明。

显示出来是这样:

  1. 粘贴时添加的小尾巴

我在苏卡卡dalao的基础上进行了一些修改,如果复制的代码块,添加小尾巴会是真恶心。

但是如何排除呢?我可以给出代码块的标签,一般是<pre>,但是我的代码块也有在<span>中的。

龙大佬给了个方法,查看getSelection方法的API
以下可以在浏览器的开发者工具 - console 中测试:

光标选中内容的对象

1
window.getSelection()

获取选中的内容

1
window.getSelection().toString()

光标所在的node(?)

1
window.getSelection().anchorNode

父节点标签名字

1
window.getSelection().anchorNode.parentNode

只需要看父节点标签名字是不是PRE或者SPAN即可

还有长度判断,这块苏卡卡的原脚本是有的

修改后的 js 如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
!function() {
function a(a) {
var b, c;
if (a.preventDefault(), b = window.getSelection().toString() + "<br><br>本文采用 CC BY-NC-SA 4.0 许可协议,著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。<br>作者:驱蚊器喵#ΦωΦ<br>来源:" + document.title + "<br>链接:" + window.location.href, c = window.getSelection().toString() + "\n\n本文采用 CC BY-NC-SA 4.0 许可协议,著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。\n作者:驱蚊器喵#ΦωΦ\n来源:" + document.title + "\n链接:" + window.location.href, a.clipboardData)
a.clipboardData.setData("text/html", b), a.clipboardData.setData("text/plain", c);
else if (window.clipboardData) return window.clipboardData.setData("text", c)
}
document.body.addEventListener("copy", function(b) {
var sn = window.getSelection().anchorNode.parentNode.nodeName.toUpperCase();
(sn !== 'CODE' && sn !== 'SPAN' && sn !== 'TD') && window.getSelection().toString().length > 10 && a(b)
})
}();
</script>

然后我将这块js放到主题目录里,布局中页脚部分,也就是:

1
themes/indigo/layout/_partial/footer.ejs

到时候生成静态文件的时候,footer应该是每个页面都会存在的。
我也不知道合不合适,hexo s测试了一下是可以正常运行的.

Update:

  1. 我自己在生活中,抄(copy)自己博文中的代码时,发现被加了小尾巴(mdzz???),排查后发现,双击复制单行代码时,此时父节点的名字为TD,所以还需排除TD标签。

  2. 加上大写转换,兼容 XML、XHTML 文档,详见苏卡卡大佬的评论。