删除英文标题,改为中文标题,之后怎么做 301 跳转

博客应该使用英文标题还是中文标题 一文中,详细描述了删除英文标题,改为中文标题的必要性。但是,把所有英文标题,改变成中文标题,可是有副作用的,曾经在搜索引擎上的 SEO 权重,曾经的英文标题链接,还存在。用户如果搜出几十个英文标题,点进去发现文章已经删除,那还了得?所以,我们需要把曾经的英文标题,做一个 301 跳转操作。

找到标题

找到曾经用的英文标题。这个应该在删除前有备份。

现在最新用的中文标题,对 MediaWiki 站点来说可以在 AllPages 界面找到。

匹配规则

需要建立一个 redirects20251003.map 文件,里面以这样的形式,写好英文标题与中文标题的对应。

blog/What_basic_knowledge_should_you_know_before_using_a_computer /blog/%E4%BD%BF%E7%94%A8%E7%94%B5%E8%84%91%E5%89%8D%E8%A6%81%E4%BA%86%E8%A7%A3%E5%93%AA%E4%BA%9B%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86
/blog/How_to_disable_windows_10_desktop_ads /blog/%E6%80%8E%E6%A0%B7%E5%85%B3%E9%97%ADWindows10%E6%A1%8C%E9%9D%A2%E5%B9%BF%E5%91%8A
/blog/Why_cant_i_open_compressed_files /blog/%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6%E6%89%93%E4%B8%8D%E5%BC%80%E6%98%AF%E6%80%8E%E4%B9%88%E5%9B%9E%E4%BA%8B
/blog/Is_buying_a_secondhand_laptop_worth_it /blog/%E4%B9%B0%E4%BA%8C%E6%89%8B%E7%AC%94%E8%AE%B0%E6%9C%AC%E7%94%B5%E8%84%91%E5%88%92%E7%AE%97%E5%90%97
...

RewriteMap

采用 Apache 的 RewriteMap 方式做跳转。把以下代码添加进你的 VirtualHost 的 443 节点。

# Put RewriteMap declaration near the top of the vhost (or global server config)                                               
# 因为全部从英文标题变为中文标题,所以有此 redirects20251003.map                                                               
RewriteEngine On
RewriteMap redirects txt:/etc/apache2/redirects20251003.map

# Map lookup by REQUEST_URI                                                                                                    
# 据 ChatGPT 说这会使查表在 Apache2 内部,速度更快                                                                             
RewriteCond %{REQUEST_URI} (.*)
RewriteCond ${redirects:%1|NOT_FOUND} !NOT_FOUND
RewriteRule ^ ${redirects:%1} [R=301,L,NE]

redirects20251003.map 文件里的目标必须是“未被双重编码”的 percent-encoded 路径(例如 /blog/%E6%80%8E%E6%A0%B7...),不要把 % 再编码成 %25。

NE 告诉 mod_rewrite 不对替换字符串进行 URL-escaping,从而保持 map 文件里的 %E6... 原样输出。

添加规则后,检验一下有没有语法错误,之后重启一下服务。

sudo apachectl configtest
sudo systemctl reload apache2

细节调整

由于曾经用的英文标题,在自建时候总有不小心以小写英文字母开头的,那么备份时的英文标题自然是小写英文字母开头。

然而,MediaWiki 会自动把任何小写字母开头的标题,改为大写字母开头。

这就导致,匹配规则里有小写,服务器能看到小写字母开头的英文标题,做好了 301 跳转;但是 MediaWiki 的大写字母开头的标题,服务器不知道,没法跳转。

只需要把曾经用的英文标题,在匹配规则里,全部改为大写英文字母开头,即可与 MediaWiki 的自动大写规则完美适应。用 Emacs 的话可以这样修改:用正则表达式,把 \(^/blog/\)\(.\) 替换为 \1\,(upcase \2)。含义如下:

\( \) 包裹一个正则表达式
^ 行首
. 任意单个字符
\1 第一个正则表达式
\,( ) 运行一个函数
upcase 改为大写字母
\2 第二个正则表达式

总结

这样,搜索引擎中所有散落的英文标题,当用户尝试访问时,会自动跳转到最新的中文标题。旧的英文标题积累的 SEO 权重,也会传递到新的中文标题链接。而中文标题链接,也会如改动之前预料的那样,在网上捕获更多的用户搜索关键词。这样就完成了一个完整的博客标题迁移。