起因
首先说明一下,这里所指的hexo中两个source文件夹,一个是hexo根目录中自带的,一个是安装的主题的文件夹中的,比如对于next主题,路径就是theme/next/source。
起初,根据我的这篇nginx+next添加404页面方法的文章的步骤,我完美实现了hexo访问不存在页面时跳转到自定义的404页面功能。根据当时的步骤,我是把自己新建的404.html文件放入到了next主题的source文件夹中,然后执行hexo clean和hexo g指令,此时访问一个不存在的页面,就会跳转到我自定义的这个404.html页面中,页面中内容是腾讯公益。
但是众所周知,不管是hexo的source文件夹,还是主题中的source文件夹,我们在对hexo博客进行编译生成的时候,都会自动将这两个source文件夹中的所有内容传送到hexo的public文件夹中的。所以按理来说,我不管是把404.html放到hexo的source还是主题的source文件夹中,最终的实现效果应该都是一样的啊!!!
然而现实并不是,根据实践我发现,把404.html放到hexo根目录的source中时,如果我打开一个不存在的页面,就会闪现出hexo博客的页面然后再进入到404页面中,而且布局也乱了。如果把404.html放到next主题的source文件夹中,那么我访问一个不存在的页面时,就会直接跳转到404.html页面,根本没有闪现出hexo网页。一开始真是让我百思不得其解,毕竟hexo只是静态博客啊。
原因分析
当然后来发现这只是表象,根本原因在于,hexo把放到根目录source中的所有文件,当作了hexo的page页面来处理和显示。也就是说,把404.html当作_post文件夹中的所有文章一样来显示到hexo既定的布局中了,是作为一篇文章来显示的。而主题的source文件夹中的所有文件就不会被当作网页中的文章来显示了。
后来想到难道是有某个控制模块存在,所以导致了同样一个404.html文件,并且都在public文件夹中,显示模式却大不相同。想了很多,最后想着hexo每次编译完成不是都会在根目录生成一个db.json文件吗,这个是hexo的数据库,json格式的txt文件。里面应该会保存着相关的信息,来实现这种区分。
研究db.json文件内容
db.json文件非常的长,幸好目前网站的文章数量不多,不然真挺恐怖的,很少见到这么长的json。里面记录了你所有的文章、目录、标签,以及他们之间的对应关联关系,还有一些其他的配置。
经过查找在models/asset中找到了themes/next/source/404.html文件。注意,此时他后面的renderable字段的值是“1”。并且在asset数组中有很多额外添加的布局文件之类的renderable都是“1”。这可能表明了这些文件都是作为资源,需要被直接渲染到全局顶层的。
然后我又尝试了将404.html文件移动到hexo根目录的source中进行编译。这次在cache对象数组中才能找到source/404.html文件,并且是没有renderable字段的。asset中不再存在404.html。但是其他文件比如存放在根目录source中的txt文件就同时出现在asset和cache数组中,并且renderable为“0”。
总结原因
看起来是hexo在编译的时候对主题内source文件夹中的html、css、js之类的文件有特殊的处理。通过这种处理保证了它们的渲染正确。而不至于被当作一篇普通文章或者一个普通page或者普通txt文档等。所以404.html文件还是应该放在主题目录中的source文件夹中。