0%

批量替换文章图片链接为jsdelivr cdn链接

使用jsdelivr cdn加速网站图片访问速度。

1. jsdelivr cdn的简单使用

新建一个GitHub仓库,提交图片文件到仓库。然后使用下面的链接就能访问了:

1
2
3
https://cdn.jsdelivr.net/gh/user/repo@latest/imgs/test.png
#比如我的一个链接
https://cdn.jsdelivr.net/gh/maplesugarr/blog-assets@latest/imgs/maple-leaf-avatar.jpg

墙内也可以顺畅访问(我并不在乎墙内用户,需要本站信息的人应该自行解决。),https://github.com/jsdelivr/jsdelivr#china 说明:

jsDelivr works perfectly inside China!

2. 本站的图片和链接配置

本站一直使用文章资源文件夹来保存图片,具体就是设置站点配置文件_config.yml

/_config.yml
1
post_asset_folder: true

当资源文件管理功能打开后,Hexo将会在你每一次通过 hexo new [layout] <title> 命令创建新文章时自动创建一个文件夹。这个资源文件夹将会有与这个文章文件一样的名字。将所有与你的文章有关的资源放在这个关联文件夹中之后,你可以通过相对路径来引用它们,这样你就得到了一个更简单而且方便得多的工作流。

文章中引用图片

1
2
{% asset_img bg-1.png  %}
<img src="bg-1.png" width="480px" >

另外,本站的永久链接配置是:

1
permalink: :category/:urlname/

其中urlname是写在Front-matter中的,比如这篇文章的Front-matter:

1
2
3
4
5
6
7
8
title: 批量替换文章图片链接为jsdelivr cdn链接
urlname: next-jsdelivrcdn-for-postimg
date: 2020-03-11 15:10:00
tags:
- 静态博客
- hexo
- next主题
categories: hexo

这篇文章的链接就是 https://blog.maplesugar.top/hexo/next-jsdelivrcdn-for-postimg

3. 批量替换文章图片链接为jsdelivr cdn链接

观察hexo generate生成文章的图片链接:

1
2
3
4
<!-- 这种 {% asset_img bg-1.png  %} 引用方式生成的图片链接 -->
<img data-src="/hexo/next-theme-custom-background-img-using-unsplash/bg-1.png">
<!-- 这种 <img src="bg-1.png" width="480px" > 引用方式生成的图片链接 -->
<img width="600px" data-src="/raspberrypi/raspberrypi-summary/sumup1.png">

所以把图片的data-src属性上加上jsdelivr cdn链接就可以了。当然需要把图片上传到GitHub仓库的相应目录,我是把hexo generate生成的文件夹直接复制到GitHub仓库中,这样就不用新建/category/urlname这样的文件夹了。

/script/jsdelivrcdn-for-postimg.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
'use strict';
var cheerio = require('cheerio');

//data https://hexo.io/zh-cn/docs/variables
hexo.extend.filter.register('after_post_render', function(data){
var config = hexo.config;
if(config.post_asset_folder){
var link = data.permalink;//页面的完整网址
console.log("页面的完整网址 "+link);//https://blog.maplesugar.top/hexo/next-theme-custom-background-img-using-unsplash/

//link= "https://blog.maplesugar.top/hexo/next-theme-custom-background-img-using-unsplash/";
if(link.lastIndexOf('/') != (link.length-1)) {
console.log("不是文章链接,跳过");
return;
}

//page.content 页面的完整内容 string
//page.excerpt 页面摘要 string
//page.more 除了页面摘要的其余内容
var toprocess = ['excerpt', 'more', 'content'];
for(var i = 0; i < toprocess.length; i++){
var key = toprocess[i];

console.log("处理页面的 " + key + "部分");

var $ = cheerio.load(data[key], {
ignoreWhitespace: false,
xmlMode: false,
lowerCaseTags: false,
decodeEntities: false
});
//替换img内的标签
//观察生成的post.content中img,有下面两种
//在post中写的img标签,有高度宽度。<img width="600px" data-src="/raspberrypi/raspberrypi-summary/sumup1.png">
//在post中写的{% asset_img bg-1.png %}标签。<img data-src="/hexo/next-theme-custom-background-img-using-unsplash/bg-1.png">
$('img').each(function(){
if($(this).attr('data-src')||$(this).attr('src')){
//注意文章内容包含`var toprocess = ['excerpt', 'more', 'content']`,
//不同内容里面的图片链接并不是一样的,有的是src,有的是data-src。
// For windows style path, we replace '\' to '/'.
var src = ($(this).attr('data-src')||$(this).attr('src')).replace('\\', '/');
console.log("找到的img链接 "+src);

//src去除前后空格
src = src.replace(/(^\s*)|(\s*$)/g, "");

//开始是/,以gif/png等结尾
if(/^\/.*\.(gif|png|jpg|bmp|jpeg)$/i.test(src)) {
console.log("测试img链接通过 "+src);

$(this).attr('data-src', "https://cdn.jsdelivr.net/gh/maplesugarr/blog-assets@latest/posts" + src);
console.log("替换img链接为 " + "https://cdn.jsdelivr.net/gh/maplesugarr/blog-assets@latest/posts" + src);
}else{
console.info&&console.info("注意,这个img标签,data-src没有通过测试");
}
}else{
console.info&&console.info("注意,这个img标签,没有data-src属性,或者src属性");
console.info&&console.info($(this));
}
});
data[key] = $.html();
}
}
});

上面的脚本放到/scripts文件夹下面就会运行,注意上面的代码是注册到hexo的生命周期”after_post_render”上的,所以一定要先执行hexo clean来清除缓存,然后执行hexo generatehexo server触发post render,它才会执行。

为什么不写成插件呢?不同的人用的图片引用方式不一样,文章网址生成方式也不一样,据我所知,有的是用hexo-abbrlink生成文章链接。写成插件就要兼容各种方式,我比较懒,对前端技术也不感冒。小伙伴们只需要观察自己生成的图片链接格式,稍微改改就能用了。