针对防盗链的图床解决方案

太久没用hexo导致现在发现好多图都挂了,整了个解决方案。

众所周知,HEXO是以Node.js为基础的一个博客模板。你可以使用Markdown来生成你的文章,虽然有自己的标签,但是我通常还是会使用![xx](xx)的方式来插入图像,仅仅是因为打起来快。但是最近使用时发现存在微博的图都挂了。通过查阅文章我发现可以通过在img标签中加入referrerpolicy="no-referrer"的属性来达到显示。下面是对比效果:

未加入属性前:
俺是图图

加入了属性后:
俺是图图

为了适应我的写作习惯,我决定整个模板一劳永逸。
首先一个小tips,hexo是以node.js为基础的博客模板,它默认使用markd引擎来渲染md文件成为html,那么为了达到我们的效果我们需要修改对应的引擎。

hexo引擎在根目录\node_modules\hexo-renderer-marked中。

打开lib\renderer.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
// Support AutoLink option
Renderer.prototype.link = function(href, title, text) {
var prot;

if (this.options.sanitize) {
try {
prot = decodeURIComponent(unescape(href))
.replace(/[^\w:]/g, '')
.toLowerCase();
} catch (e) {
return '';
}

if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
return '';
}
}

if (!this.options.autolink && href === text && title == null) {
return href;
}

var out = '<a href="' + href + '"';

if (title) {
out += ' title="' + title + '"';
}

out += '>' + text + '</a>';
return out;
};


根据代码逻辑,我们能够快速定位到该渲染器继承的类


俺是代码

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
class Renderer<T = never> {
constructor(options?: MarkedOptions);
options: MarkedOptions;
code(code: string, language: string | undefined, isEscaped: boolean): string | T;
blockquote(quote: string): string | T;
html(html: string): string | T;
heading(text: string, level: 1 | 2 | 3 | 4 | 5 | 6, raw: string, slugger: Slugger): string | T;
hr(): string | T;
list(body: string, ordered: boolean, start: number): string | T;
listitem(text: string): string | T;
checkbox(checked: boolean): string | T;
paragraph(text: string): string | T;
table(header: string, body: string): string | T;
tablerow(content: string): string | T;
tablecell(
content: string,
flags: {
header: boolean;
align: "center" | "left" | "right" | null;
},
): string | T;
strong(text: string): string | T;
em(text: string): string | T;
codespan(code: string): string | T;
br(): string | T;
del(text: string): string | T;
link(href: string | null, title: string | null, text: string): string | T;
image(href: string | null, title: string | null, text: string): string | T;
text(text: string): string | T;
}


确认了模板发现如果要修改图像就需要重载它的image属性,因为逻辑与链接类似,所以在代码中加入:


俺是新加的代码

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
// Add weibo image support
Renderer.prototype.image = function(href, title, text) {
var prot;

if (this.options.sanitize) {
try {
prot = decodeURIComponent(unescape(href))
.replace(/[^\w:]/g, '')
.toLowerCase();
} catch (e) {
return '';
}

if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
return '';
}
}

if (!this.options.autolink && href === text && title == null) {
return href;
}

var out = '<img src="' + href + '"';

if (title) {
out += ' title="' + title + '"';
}

out += 'alt="' + text + '"';


out += 'referrerpolicy="' + 'no-referrer' + '" />';
return out;
}


最后重新生成文章并发布就完事了~~~