一、被删掉的页面,其实大多数还在被访问
改版、合并栏目、清理低质内容之后,服务器上会出现一批返回 404 的地址。多数人的处理方式是:确认这些页面已经不需要了,然后就不管了。但搜索引擎的索引里有它们,外部网站的链接指向它们,读者的收藏夹里也存着它们。一次 404 不是「干净了」,而是「一个本来还能承接流量的入口,突然变成了死路」。
在站点持续更新的情况下,404 的出现几乎是常态:每次改 URL 规则、每次合并分类、每次删掉一个过时的单页,都会产生一批。所以关键不是「避免 404」,而是有没有一套机制,让这些旧地址在被访问时仍然把人送到正确的地方。本文讲的是删页之后的 404 兜底与重定向治理,重点是执行顺序和判断标准,而不是某个插件的安装步骤。
二、先分清三种「没有页面」,处理方式完全不同
在处理之前,必须先把 404 分成三类,因为它们在语义上不一样,对搜索引擎传达的信号也不一样。
第一类:页面搬走了,内容还在。这是最应该重定向的情况。URL 从带日期变成不带日期、分类从「建站教程」改成「技术教程」、文章 slug 从中文改成英文,内容本身没变,只是地址变了。这类用 301 永久重定向到新地址,权重和用户都能承接。
第二类:内容确实删掉了,且没有替代品。比如一篇写错的教程、一个已经下线的服务介绍。这类正确做法是返回 410(或直接 404),并给出一个友好的提示页,引导读者去首页或搜索。不要 301 到首页——这会让搜索引擎把大量无关的旧地址都视为首页的别名,属于典型的软 404 问题。
第三类:内容删了,但有同类替代内容。这类最容易被忽略,也最有价值:如果能找到同一主题的新文章,就重定向到那一篇;如果只是把几篇合并成一篇,就重定向到合并后的那一篇。这不仅保住了访问者,也保住了原有的外链权重。
判断三类的方法很实际:打开旧地址,问自己「如果读者点进来,他最想看到什么」。答案是新地址的用第一类,是同类文章的用第三类,什么都不是的就用第二类。
三、执行顺序:先摸清底数,再动手改
最容易出错的做法是「先写一堆重定向规则再去验证」。正确顺序是反过来的:先拿到真实数据,再决定改哪些。整个流程分四步。
第一步,拿到 404 清单。最直接的方式是分析访问日志,把状态码为 404 的请求按 URL 聚合,按次数排序。日志里已经记录了每一次访问,不需要额外埋点。
# 按出现次数排序的 404 URL 清单(字段位置按自己的日志格式调整)
awk '$9 == 404 {print $7}' /var/log/nginx/access.log \
| sort | uniq -c | sort -rn | head -50如果日志已经轮转掉,就用站点自身的 404 日志、搜索引擎后台的死链报告、或者第三方监控工具补齐。关键是拿到「真实有人在访问的旧地址」,而不是凭记忆瞎猜。
第二步,给每个地址分类。对照上面的三类判断,把清单整理成一张表:旧地址、处置方式(301 到某处 / 410 / 暂不处理)、目标地址、判断依据。这张表就是后续所有工作的依据,也能作为以后复盘的材料。
第三步,确认目标地址本身是有效的。这一步经常被跳过。如果 A 重定向到 B,而 B 本身也是 404,等于把死路延长了一节。批量重定向之前,先对每个目标地址做一次请求检查,全部返回 200 才写进去。
第四步,分批上线并观察。不要一次改几百条,先上访问量最高的前二十条,观察一周的日志:这些旧地址是否还有大量 404、重定向是否形成链、有没有出现循环。确认没问题再上剩下的。
四、重定向怎么写才不会坑自己
重定向的规则本身很简单,但有几个细节决定了它会不会变成新的问题。
用 301,不要用 302。301 表示永久搬移,搜索引擎会把旧地址的权重转移到新地址;302 是临时,旧地址会长期留在索引里。用错这一条,等于白做。
只允许一跳。A 到 B、B 到 C 这种链式重定向,每一次都要多一次请求,权重在传递中会被削弱,而搜索引擎也会提示「重定向链」。写规则时要检查目标地址本身是不是已经是另一个重定向的起点,发现链就把它改成从 A 直接到 C。
不要整站重定向。「所有找不到的页面都跳到首页」看起来最省事,实际上会让大量无关旧地址都指向首页,搜索引擎会把它视为软 404,同时读者点进来之后发现内容完全不对,跳出率极高。宁可返回一个带搜索框的 404 页。
规则要有优先级意识。重定向通常是按顺序匹配的,正则写得过于宽泛会吃掉本来要单独处理的地址。经验顺序是:先写精确匹配的单条路径,再写带通配的批量规则,最后才是兜底规则。
换域名和改路径不要混在一批。如果同时面临域名变更和路径调整,应该先做域名变更(旧域名整站 301 到新域名,路径不变),稳定一段时间后再做路径调整。两件事同时做,重定向规则会互相干扰,排查起来非常痛苦。
五、常见的四种错误配置
错误一:大小写敏感导致漏匹配。URL 路径在某些服务器上是大小写敏感的,而用户和外部链接里的写法未必一致。批量规则要显式处理大小写,或者统一用忽略大小写的匹配方式。
错误二:带参数的地址没被覆盖。旧文章地址后面经常挂着追踪参数,规则只匹配了无参数的形式,带参数的请求仍然是 404。写规则时要么把查询串一起转发,要么显式忽略它。
错误三:尾斜杠不一致。带斜杠和不带斜杠在很多配置里是两个不同的地址,只重定向其中一个,另一个仍然会 404,还可能造成重定向循环。规则里要同时覆盖两种形式。
错误四:在应用层和服务器层都写了重定向。两边规则不一致时,会出现「先跳到 A,应用层又把它跳到 B」的链,非常难排查。确定一个地方写,另一处不要再重复。
六、404 页面本身也要设计
重定向覆盖不到的地址,最终会落到 404 页。这个页面不应该只是一句「页面不存在」。
一个有用的 404 页至少包含三样东西:一句说明、一个搜索框、几个热门内容入口。搜索框的价值在于读者自己知道他要什么,只要把关键词交给他去站内搜索,很多人能在一次点击内找到替代内容。热门入口则覆盖那些「其实不知道自己想要什么」的人。
另外两个技术细节:状态码必须是真正的 404。很多框架的「友好 404 页」实际返回的是 200,这会让搜索引擎认为这个地址是正常页面,从而把大量垃圾地址收录进索引,这是软 404 最典型的形态。用一条命令就能验证:请求一个肯定不存在的地址,看返回的状态码。
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.com/definitely-not-here-12345第二个细节是不要在 404 页上放自动跳转。几秒后跳回首页,看起来「友好」,实际会让读者来不及看清说明,也会被搜索引擎当成变相重定向。让读者自己决定是否回首页。
七、把重定向当资产来维护
重定向规则写进配置文件之后,很容易变成只增不减的历史包袱。三年下来可能积累几百条规则,其中有相当一部分目标地址已经再次失效,形成了新的死链。
所以要有定期维护:每季度跑一次全量检查,对所有重定向规则的目标地址做一次请求,凡是返回非 200 的都标出来。如果目标地址又搬了,就把规则的目标更新到最新地址;如果目标内容已经删除,就把这条规则改为 410。
这份检查脚本不需要复杂逻辑,把规则读出来、逐个请求、打印异常即可,比什么都可靠。检查结果和第三部分的清单放在一起,就形成了一份完整的「站点地址资产账本」。
还有一件事值得做:把重定向规则也纳入版本管理。每一条规则旁边写一句注释,说明为什么加、什么时候加的。半年后回来看,那句注释往往比规则本身更有价值。
八、从读者角度做最后验收
所有检查做完之后,最后一步是站在读者角度走一遍。拿三类典型的旧地址各测一次:一条访问量最高的、一条带参数的、一条有外链的。检查四件事:跳转是否只跳一次、最终页面是否 200、内容是否与读者预期一致、跳转之后地址栏显示的是新地址。
这四个检查都不需要工具,用浏览器手工做一遍就够,但它能发现脚本检查发现不了的问题——比如跳转到了正确的内容,但地址栏还是旧地址,读者复制分享出去的链接依然是失效的。
九、小结
删页之后的治理,核心是三步判断和一套顺序:先分清「搬走了、删掉了、有替代」三类,再从日志里拿到真实清单而不是凭记忆,最后用只跳一次、不带链、不整站跳首页的规则把它们落地。规则不是写一次就完,它需要季度体检,也需要写注释。做好了,旧的链接会一直是活的入口;做不好,每一次改版都在给自己制造死路。