解决使用Typora,Hexo博客的图片无法显示的坑

配置

  • Win10
  • Typora(0.9.89 beta)
  • Hexo(4.2.1)
  • Git(2.22.0.windows.1)

问题

今天第一次开始使用Hexo,还在本地搭建呢,自信满满地把以前用typora写的一篇文章放上去测试,打开localhost:4000,一看,不对劲!图片没加载出来!

img

一琢磨,应该是Hexo和Typora之间,图片引用地址转换的问题(废话,图片没找到,肯定是地址问题)

第一次尝试

出现问题了,就上谷歌查呗。

接着按照网上的教程,打开修改Hexo配置,把hexo根目录文件夹里的全局配置文件_config.yml用 vscode 打开,修改post_asset_folder: falsepost_asset_folder: ture

上面这个改成ture呢,就是我们每次在hexo中 new 一个新文件的时候,都会在同级目录下创建一个与文件同名的文件夹。默认都是在根目录\source\_posts下的。

接着按照上面的这个创建新的资源文件夹的规律,在Typora里,文件 –> 偏好设置 –> 图像 –> 插入图片时 –> 复制到指定路径,然后确认指定路径是./${filename},勾选优先使用相对路径。

差不多是下面这个样子。

插嘴一句,因为我之前设置的复制到的路径,后面是有个.assets的,然后以前写的博客都是这样模式存图片的,突然感觉血亏。只能修改图片文件夹名字,然后在文章里面CTRL + H,全部替换,其实也还挺方便的。

最后,去hexo的根目录,右键Gir bash here,cnpm install hexo-asset-image --save,安装这个路径转换的插件。

一切都顺顺利利,hexo clean && hexo g && hexo d && hexo s 一气呵成,启动!

img

然后,然后,图片依然没有加载出来!!!没啥软用!

img

第二次尝试

看到很多把图片设置到上级目录的方法,但是我以前写的那么多,总不能全都大改吧,那多累啊,我还是决定坚持上面的方法,找找原因,毕竟两者工作量不是一个级别的:cry:

路径转换有问题,但是本地用typora看没啥问题,到hexo上就找不到,emmm,找了一圈,然后发现了问题所在。

这是根目录\source的目录结构

  • source(目录)
    • _posts(目录)
      • 文件名.md
      • 文件名(目录)
        • xxx.png(图片)

没啥问题,但是一旦使用hexo generate生成静态文件之后,就把上面的source拷贝到了根目录\public\2020\07\11文件夹下面

这是根目录\public\2020\07\11的目录结构

  • 根目录\public \2020\07\11(目录)
    • 文件名(目录)
      • 文件名.html
      • xxx.png

也就是说,生成静态文件之后,图片路径发生变化了,变到了同级目录之下了。。。。我裂开了。:sob:

那现在有点明朗了,就是这个路径转换问题,而现在没解决,那就是说之前下的那个hexo-asset-image 插件没起作用。那好办,换就完事了!

于是换了hexo-simple-image

。。。。没用

换了 hexo-image-link

。。。。没用

。。。。

裂开,第二次尝试失败!

img

第三次尝试

现在已经知道了是这个路径转换插件没起作用,换了几个,也同样没用。不过,俗话说得好,世界上百分之九十九的坑都有前辈帮你踩过了,你只要踩着坑里前辈的尸体前进就好了,他们会为你负重前行。:happy:

既然这个hexo-asset-image 插件不起作用,那改写就好了!

于是找到了这篇博客:https://ytianxia6.xyz/archives/21

打开根目录\node_modules\_hexo-asset-image@1.0.0@hexo-asset-image\index.js,然后在generate的时候,把(文件名/xxx.png)改写成(xxx.png),

两段主要改写的代码

1
2
3
4
5
// 得到文件名
var fname = data.slug;
if (fname != undefined) {
fname = fname.substring(fname.lastIndexOf('/') + 1);
}
1
2
3
4
// 如果图片路径的形式是 "文件名/图片名",则去掉"文件名/"
if (src.indexOf(fname + '/') == 0) {
src = src.substring(fname.length + 1);
}

接下来,只要把index.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
hexo.extend.filter.register('after_post_render', function(data){
var config = hexo.config;
if(config.post_asset_folder){
var link = data.permalink;
var beginPos = getPosition(link, '/', 3) + 1;
// In hexo 3.1.1, the permalink of "about" page is like ".../about/index.html".
var endPos = link.lastIndexOf('/') + 1;
// 加上路径
// var endPos = link.length;
link = link.substring(beginPos, endPos);

// 得到文件名
var fname = data.slug;
if (fname != undefined) {
fname = fname.substring(fname.lastIndexOf('/') + 1);
}

var toprocess = ['excerpt', 'more', 'content'];
for(var i = 0; i < toprocess.length; i++){
var key = toprocess[i];

var $ = cheerio.load(data[key], {
ignoreWhitespace: false,
xmlMode: false,
lowerCaseTags: false,
decodeEntities: false
});

$('img').each(function(){
// For windows style path, we replace '\' to '/'.
var src = $(this).attr('src').replace('\\', '/');
if (!/http[s]*.*|\/\/.*/.test(src)) {

// 如果图片路径的形式是 "文件名/图片名",则去掉"文件名/"
if (src.indexOf(fname + '/') == 0) {
src = src.substring(fname.length + 1);
}

console.log("this = ", $(this));
// For "about" page, the first part of "src" can't be removed.
// In addition, to support multi-level local directory.
var linkArray = link.split('/').filter(function(elem){
return elem != '';
});
var srcArray = src.split('/').filter(function(elem){
return elem != '';
});
if(linkArray[linkArray.length - 1] == srcArray[0])
srcArray.shift();
src = srcArray.join('/');
$(this).attr('src', '/' + link + src);
}
});
data[key] = $.html();
}
}
});

接着,hexo clean && hexo g && hexo d && hexo s 一气呵成,启动!

成功!!!

img