整站从 old.example.com 迁到 new.example.com,nginx 里的规则是 rewrite ^/post/(.*)$ /p/$1 permanent,没带参数。带 ?from=rss 和 ?utm_source= 的老链接全部 301 到首页,GSC 软 404 两周涨到八千条。改过两次规则顺序,仍是首页。

一开始怀疑是「部分老链接是多级目录,只写了一层的正则匹配不到」,查了一圈,方向不对。

排查方向其实有限,先把可能性排一排。规则替换时没有把原始 query 拼回去,nginx 默认会丢掉未显式引用的参数。少数情况下是首页兜底 location 把所有未匹配的地址收走,掩盖了规则的漏洞。

另外,CDN 缓存了旧的 301,改完规则边缘仍在返回首页。

带参数请求一次,看 Location 指向哪里

curl -sI 'https://old.example.com/post/1024?from=rss' | grep -i location

再往下在 rewrite 末尾补回参数,确认语法

rewrite ^/post/(.*)$ /p/$1?$args permanent;

接着核对多级目录的旧地址是否也覆盖

curl -sI 'https://old.example.com/post/2024/10/1024.html' | head -3

末了清掉边缘缓存后再验一次

curl -X PURGE 'https://old.example.com/post/1024?from=rss'

别只看报错消失,验证要多做一步。带参地址 301 到新站对应的文章页而不是首页,软 404 停止增长,两周后开始下降。

301 保留参数会让新站收到一堆无意义的 utm,最好只保留业务参数,其余在跳转后由前端清掉。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189