用重定向去掉博文的 .html 后缀
谷月姐最近有一个需求,就是用重定向(准确地说是 301 跳转)去掉博文的 .html
后缀,例如,把形如 https://blog.kukmoon.com/834aa795.html
的 URL 转变成 https://blog.kukmoon.com/834aa795/
(注意最后的斜杠)的形式。
01 S 场景
虚拟主机快到期了,我不想再续费了,想把博客部署到一个免费的托管平台。
找来找去,找到了 Cloudflare Pages (下文简称 CF Pages)。CF Pages 不用花钱,可以与 GitHub 无缝对接,在墙内外都有节点,非常适合我部署 本博。
02 C 冲突
CF Pages 会强行忽略 URL 中的 .html
后缀,例如,让形如 https://blog.kukmoon.com/834aa795.html
的网址 302 重定向到形如 https://blog.kukmoon.com/834aa795
(注意最后没有斜杠)的网址。官方称之为 Route Matching (路由匹配)[1]。经测试,它无法手动关闭。
这个问题产生了两个负面影响:
-
这个功能影响了评论的加载[2]。本博 的评论系统是 Valine,它是根据静态页面的文件名来储存评论数据的,比方说,它会把
https://example.tld/file123.html
这个页面的所有评论放在数据库的file123.html
表中。所以 本博 不同镜像的同一篇文章会共享同样的评论。但是 Route matching 去掉了.html
后缀,导致 Valine 评论系统会在数据库新建一个 file123 表,从而使得部署在 CF Pages 上的 本博镜像 不能与其他的镜像共享评论。 -
这个功能影响了搜索引擎的收录与检索。搜索引擎收录的 URL 是含有
.html
后缀的,如果去掉了这个后缀,就势必会影响搜索引擎的收录与检索。
所以,我要是把博客从虚拟主机迁移到 CF Pages,就需要妥善地处理 Route Matching 带来的这两个负面影响。
03 Q 问题:301 跳转
我的解决方案是,在虚拟主机和 CF Pages 两边都配置 301 跳转,去掉 .html
后缀,让两边的 URL 保持一致。这样,一方面可以共享评论,另一方面也不影响搜索引擎的收录和检索。
现在问题来了,如何配置 301 跳转呢?
不同的服务端,配置 301 跳转的方法不同。
我的虚拟主机用的服务端是 Apache (CPanel 面板用的是 Apache)。CF Pages 也有自己的方法。本文只介绍这两种方法。
04 A 解决:配置 301 跳转的方法
4.1 在虚拟主机上配置 301 跳转
我的虚拟主机用的是 CPanel 面板,它是用 Apache 作为 Web 服务端,需要编写 .htaccess
文件配置 301 跳转。
新建一个名为 .htaccess
的文件(如何新建以点开头的文件,请自行谷歌搜索),填入内容如下:
1 |
|
说明:
- 第 10 行打开改写功能。
- 第 12 行是改写规则。它查找匹配正则表达式
^/?([a-z0-9]+)\.html$
的字符串,并将它替换成/$1/
,$1
表示前面的正则表达式中用圆括号括起来的部分所匹配到的内容,R=301 表示 301 (永久)重定项,L 表示执行完此条规则后不再执行下面的改写规则。 - 此处的正则表达式详解:
^
表示从这里开始/
就是左斜杠本身,它不是转义字符?
表示它前面的字符出现 0 次或 1 次,经测试此处必须有这个半角问号,否则匹配失败()
用圆括号把正则表达式的一部分括起来,可以用$n
(n为从1开始的数字)表示圆括号里的正则表达式匹配到的内容[a-z0-9]
用方括号把一组字符括起来,表示匹配之里面任意一个字符,此处的意思是任意一个小写字母(a-z)或者数字(0-9)+
表示它前面的字符出现 1 次或多次[a-z0-9]+
表示至少1个小写字母或数字\.
反斜杠和句点都是转义字符,因此如果要匹配句点,需要在它前面加一个反斜杠,所以说\.
匹配.
html
就匹配html
这四个小写字母$
表示从这里结束
注意:
- 把
.htaccess
文件保存到blog/sources/
目录(此处假设我的博客源文件保存在blog/
目录里)。 - 在 macOS 系统中,默认把以句点开头的文件当作隐藏文件,所以需要按
Shift + Cmd + .
快捷键,让“访达”显示隐藏文件。
4.2 在 CF Pages 上配置 301 跳转
CF Pages 提供了文档[3],按照文档写一个重定向规则文件 _redirects
就可以啦。不过,比起 CPanel(Apache),CF Pages 几乎不支持正则表达式。
文件内容如下(只有一行)
1 |
|
说明:
*
号代表任意数量的任意字符,:splat
代表前文中的*
号匹配到的内容。- 301 代表 301 跳转。
注意:把 .htaccess
文件保存到 blog/sources/
目录(此处假设我的博客源文件保存在 blog/
目录里)。
4.3 配置 Hexo 使上述两个文件生效
我虽然把 .htaccess
和 _redirects
这两个文件放到了 blog/sources/
目录,但是,如果不配置一下 Hexo,这两个文件是不会部署到远程主机的,也就不会生效[4]。
用文本编辑器打开 _config.yml
。
-
找到
# URL
节,将permalink:
的值改成:abbrlink/
(注意前面的半角冒号和后面的半角斜杠)。让 Hexo 渲染生成的博客 URL 为不带.html
后缀的 URL。 -
找到
# Include / Exclude file(s)
节,在include:
下方添加上述两个文件名。让 Hexo 在渲染时将这两个文件也复制到public/
目录中。 -
找到
# Deploy
节,为每个远程主机添加一个新参数:ignore_hidden: false
。让 Hexo 在部署时将作为隐藏文件的.htaccess
也一并上传到远程主机。
5 结语
搞定,301 跳转测试通过。
图片版权:
题图:"File:Symbol redirect vote2.svg" by Benoit Rochon is licensed under CC BY 3.0 .
头图:Image by Jose Antonio Alba from Pixabay