用 Hexo 写中文博客,早晚会遇到这个问题:文章的 URL 是一长串 %E7%BB%99...。
这篇记录我如何把链接从「超长乱码」改成「简短固定」的完整过程,包含原理、三种方案对比和踩坑细节。
问题:中文标题进 URL 会怎样
Hexo 默认的永久链接格式是这个:
1 | permalink: :year/:month/:day/:title/ |
:title 会用文章标题作为路径。英文标题看着挺正常:
1 | https://example.com/2026/10/06/hello-world/ |
但中文标题就出问题了。我写了一篇《HexoDeck 使用指南》,生成的链接是:
1 | https://example.com/2026/10/06/HexoDeck-给Hexo找个顺手的桌面客户端/ |
浏览器会把它编码成:
1 | https://example.com/2026/10/06/HexoDeck-%E7%BB%99Hexo%E6%89%BE%E4%B8%AA%E9%A1%BA%E6%89%8B%E7%9A%84%E6%A1%8C%E9%9D%A2%E5%AE%A2%E6%88%B7%E7%AB%AF/ |
一个标题变成 150 多个字符的乱码。这带来三个实际问题:
- 复制分享很难看 —— 发到聊天软件、论坛、社交媒体里,整屏都是
%E7%BB%99 - 容易出错 —— 手动复制时漏掉一个字符就 404;有些平台不允许这种字符
- 改标题就断链 —— 标题改了,URL 跟着变,之前所有的外链、搜索引擎收录、别人收藏的书签全部失效
第三条是最致命的。URL 应该稳定不变,而文章标题常常会改。
三种解决方案对比
| 方案 | 链接形式 | 可读性 | 稳定性 | 依赖插件 |
|---|---|---|---|---|
| 拼音转换 | /posts/hexo-wen-zhang-lian-jie/ |
✅ 可读 | ❌ 改标题就变 | hexo-permalink-pinyin |
| 短码(abbrlink) | /posts/461fc5c1/ |
❌ 不可读 | ✅ 永久固定 | hexo-abbrlink |
| 缩短结构 | /posts/给Hexo.../ |
✅ 可读 | ❌ 改标题就变 | 无 |
缩短结构只是把日期段去掉,中文编码问题依然存在 —— 不解决问题。
拼音方案可读性最好,还对 SEO 友好(URL 里有关键词)。但长标题会变得非常冗长,比如《HexoDeck —— 给 Hexo 找个顺手的桌面客户端》会变成:
1 | /posts/hexodeck-gei-hexo-zhao-ge-shun-shou-de-zhuo-mian-ke-hu-duan/ |
而且多音字可能转换错误,改标题链接还是会变。
短码方案是中文博客最常用的做法,也是我最终选的。链接短、绝对不会有编码问题,最关键的是链接写入文章元数据后永久不变。
代价是不可读、URL 里没有关键词。但对个人博客来说,链接稳定比关键词更重要 —— 你不会希望读者收藏的文章链接某天失效。
实施:改用 abbrlink
第一步:安装插件
1 | npm install hexo-abbrlink --save |
第二步:修改站点配置
打开站点根目录的 _config.yml,找到 URL 那一段,修改 permalink 并加上 abbrlink 配置:
1 | # URL |
关于格式的说明:
permalink: posts/:abbrlink/——posts/前缀是我自己加的,让链接看起来有层次。你也可以直接用:abbrlink/让链接更短- 如果按日期分目录可以用
:year/:month/:day/:abbrlink/,但短链的意义就在于短,一般不加 trailing_index: false/trailing_html: false建议一起改,去掉链接尾部多余的/index.html
关于算法的说明:
crc32生成十六进制短码(如461fc5c1、686a239—— 最多 8 位,前导零会省略),crc16只有 4 位(如a1b2)- crc16 更短,但碰撞概率高(不同文章可能算出同一个码,导致链接冲突),建议用 crc32
rep: dec会生成纯数字(如1176357825),比 hex 长,一般不用
第三步:重新生成
1 | hexo clean |
必须执行 hexo clean —— 否则 Hexo 的增量缓存不会重新计算链接,旧的中文目录还会留在 public/ 里。
生成时日志会显示每篇文章分配到的短码:
1 | INFO Generate link [461fc5c1] for post [source/_posts/HexoDeck-给Hexo...md] |
第四步:验证
打开 public/posts/ 目录,应该看到短码命名的文件夹:
1 | public/posts/ |
启动预览确认链接可以访问,旧的中文长链接目录已经消失。
关键机制:链接写进了文章里
这一步很重要 —— abbrlink 会把生成的短码写入每篇文章的 front-matter:
1 |
|
这意味着:
- 链接从此固定 —— 以后改标题,URL 仍然是
9daba997,外部引用不会失效 - 短码可手动指定 —— 想给某篇重要文章一个好看的自定义短码?直接改 front-matter 里的
abbrlink值即可(注意别和其他文章重复) - 不要手动删除 —— 删掉后下次生成会重新计算,可能得到不同的码,导致链接变化
踩过的坑
改完链接后必须 clean
我第一次改完配置直接 hexo generate,结果 public/ 里新旧目录同时存在 —— 新的短码目录生成了,旧的中文目录却没被删除。原因是 Hexo 的增量生成只处理变化的文件,不会清理已废弃的路径。
所以改 permalink 后一定要先 hexo clean。
别忘了同步改 url
站点配置里的 url 默认为 http://example.com,这个必须改成你的真实域名。它影响:
sitemap.xml里的链接- RSS 订阅里的链接
- 社交分享时的卡片链接
- 各种 SEO 元信息
如果 url 是错的,搜索引擎抓到的是 example.com,得不偿失。
已经有文章的话要注意
如果站点已经上线并且有外链,改 permalink 会导致所有旧链接 404。这时有两个选择:
- 在服务器配 301 重定向 —— 把旧链接永久重定向到新链接,保住已有权重
- 保持原样 —— 如果外链很少、影响不大,可以接受
我的站点还在建设阶段,没有外链负担,所以直接改了。如果你也刚开始写,越早做越好。
小结
| 项目 | 配置 |
|---|---|
| 插件 | hexo-abbrlink |
| permalink | posts/:abbrlink/ |
| 算法 | crc32 + hex(十六进制短码) |
| 关键操作 | 改完必须 hexo clean |
| 附带修改 | url 改真实域名、关闭 trailing_index / trailing_html |
改完之后链接从 150 多字符的乱码变成 posts/461fc5c1/,复制分享干净多了,而且以后再改标题也不怕断链。
如果你用的是图形化工具管理博客,这些配置同样可以直接编辑 —— 比如 HexoDeck 的「设置 → 高级」页就能直接改 _config.yml,改完预览自动重启。
评论