用 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 多个字符的乱码。这带来三个实际问题:

  1. 复制分享很难看 —— 发到聊天软件、论坛、社交媒体里,整屏都是 %E7%BB%99
  2. 容易出错 —— 手动复制时漏掉一个字符就 404;有些平台不允许这种字符
  3. 改标题就断链 —— 标题改了,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 里没有关键词。但对个人博客来说,链接稳定比关键词更重要 —— 你不会希望读者收藏的文章链接某天失效。

第一步:安装插件

1
npm install hexo-abbrlink --save

第二步:修改站点配置

打开站点根目录的 _config.yml,找到 URL 那一段,修改 permalink 并加上 abbrlink 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
# URL
url: https://你的域名
permalink: posts/:abbrlink/
permalink_defaults:
pretty_urls:
trailing_index: false # 去掉链接尾部的 /index.html
trailing_html: false # 去掉链接尾部的 .html

# abbrlink 配置
abbrlink:
alg: crc32 # 算法:crc32(默认)或 crc16
rep: hex # 进制:hex(默认)或 dec
drafts: false # 是否也给草稿生成

关于格式的说明:

  • 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
2
hexo clean
hexo generate

必须执行 hexo clean —— 否则 Hexo 的增量缓存不会重新计算链接,旧的中文目录还会留在 public/ 里。

生成时日志会显示每篇文章分配到的短码:

1
2
INFO  Generate link [461fc5c1] for post [source/_posts/HexoDeck-给Hexo...md]
INFO Generated: posts/461fc5c1/index.html

第四步:验证

打开 public/posts/ 目录,应该看到短码命名的文件夹:

1
2
3
public/posts/
├── 461fc5c1/
└── 9daba997/

启动预览确认链接可以访问,旧的中文长链接目录已经消失。

关键机制:链接写进了文章里

这一步很重要 —— abbrlink 会把生成的短码写入每篇文章的 front-matter:

1
2
3
4
5
---
title: 测试
date: '2026-10-05 08:24:34'
abbrlink: 9daba997 # ← 插件自动写入
---

这意味着:

  • 链接从此固定 —— 以后改标题,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。这时有两个选择:

  1. 在服务器配 301 重定向 —— 把旧链接永久重定向到新链接,保住已有权重
  2. 保持原样 —— 如果外链很少、影响不大,可以接受

我的站点还在建设阶段,没有外链负担,所以直接改了。如果你也刚开始写,越早做越好。

小结

项目 配置
插件 hexo-abbrlink
permalink posts/:abbrlink/
算法 crc32 + hex(十六进制短码)
关键操作 改完必须 hexo clean
附带修改 url 改真实域名、关闭 trailing_index / trailing_html

改完之后链接从 150 多字符的乱码变成 posts/461fc5c1/,复制分享干净多了,而且以后再改标题也不怕断链。

如果你用的是图形化工具管理博客,这些配置同样可以直接编辑 —— 比如 HexoDeck 的「设置 → 高级」页就能直接改 _config.yml,改完预览自动重启。