直接回答:URL 变更不会让引用立刻消失,伤害是滞后的——模型和索引里存的还是旧地址,等它们重新抓取时才发现内容已经不在了。保住引用只需要三件事:每一条旧地址都有 301 指向新地址、跳转链不超过一跳、sitemap 与站内链接同步更新并保留至少一年。

伤害是滞后的,所以最容易误判

改完 URL 的当天,你去看 AI 搜索,往往会发现引用还在——因为索引里存的还是旧地址。真正的下滑出现在之后的两到六周,那时爬虫重新访问旧地址,发现是 404,才把记录清掉。

这种滞后带来一个典型误判:改完没出问题,就以为不用管了,等发现问题时已经过去一个月,旧地址的外部链接和引用记录都失效了。

所以判断标准很简单:改 URL 之后,旧地址必须永远有效,只是把用户和爬虫送到新地方。

301 是唯一正确的迁移手段

几种常见做法的差别:

做法 效果
301 永久跳转 ✅ 传递权重与引用,标准做法
302 临时跳转 ⚠️ 短期可用,长期会被当作临时状态
直接返回 404 ❌ 引用与权重丢失
新旧地址都返回 200 同一内容 ❌ 重复内容,两个地址互相稀释
用 JavaScript 跳转 ❌ 抓取阶段经常执行不到

**只有 301 是明确告诉对方"这个地址永久搬走了"的信号。**其他方式要么不传递权重,要么在抓取环节就直接断掉。

第五种情况值得单独说:把新旧两个地址都保留、都返回 200,看起来"两边都能访问",实际是让两个地址争夺同一份内容,最终两个都受损。

旧地址映射要写进配置文件,长期保留

在 nginx 里做逐条映射是最直接的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 旧文章地址 → 新地址
location = /old-post-title.html {
return 301 /posts/new-post-title/;
}

# 整段路径迁移
location ^~ /blog/ {
return 301 /posts/$1;
}

# 分类页结构变化
location = /category/geo/ {
return 301 /categories/geo/;
}

地址多的时候,用 map 集中管理更清晰:

1
2
3
4
5
6
7
8
9
10
11
12
map $request_uri $redirect_target {
default "";
/old-a/ /posts/a/;
/old-b/ /posts/b/;
/old-c/ /posts/c/;
}

server {
if ($redirect_target != "") {
return 301 $redirect_target;
}
}

几个要点:

  • location = 做精确匹配,避免规则互相干扰
  • 映射表放在配置文件里,不要放在数据库或脚本里——它需要长期存在
  • 改完必须实际请求一遍旧地址,看返回的 Location 是否正确

跳转链必须控制在一次以内

A → B → C 这种多级跳转是常见的隐性损耗:每多一跳,抓取预算和权重传递都会被削弱,部分爬虫在第二跳就放弃了。

自查方法:

1
curl -sI https://example.com/old-url/ | grep -iE "^(HTTP|location)"

如果返回的 Location 指向的地址还会再跳一次,就把映射直接改成指向最终地址,把中间那一环删掉。

内部改写会让跳转规则陷入死循环

本站做过一次地址规范化:把 /topic/index.html 这类带文件名的地址统一跳到目录形式 /topic/。第一版配置是这样写的:

1
2
3
4
# ❌ 有问题的写法
location ~ ^(?<dir>/.*)/index\.html$ {
return 301 $dir/;
}

上线后除首页外全站瘫痪——访问 /topic/ 会无限跳转。

原因是 nginx 在处理目录请求时,会在内部把 /topic/ 改写成 /topic/index.html,改写后的地址又匹配了这条 location 规则,于是 /topic/ 被要求跳到 /topic/,形成死循环。

正确的做法是判断客户端原始请求,而不是内部改写后的地址:

1
2
3
4
# ✅ 正确写法
if ($request_uri ~ ^(/(?:[^?]*/)?)index\.html(?:\?|$)) {
return 301 $1;
}

$request_uri 保存的是浏览器实际请求的地址,不受内部改写影响,因此不会自我循环。

这个坑靠本地静态预览完全看不出来——静态服务器没有内部改写行为。涉及跳转规则时,一定要在真实 nginx 环境(哪怕是临时实例)验证,而不是只在本地看页面能不能打开。

迁移完成后有四件事必须做

动作 原因
重新生成并提交 sitemap.xml 让爬虫尽快发现新地址
更新站内所有指向旧地址的链接 内链走旧地址会持续产生跳转
检查 robots.txt 里的地址是否过期 站点地图声明指向旧文件会失效
保留 301 至少一年 外部链接与索引的更新周期可能很长

另外注意:**已经发布过的地址尽量不要再改。**迁移本身是有成本的,规划阶段多想一步,比事后修补省事得多。

常见问题(FAQ)

换了域名,旧域名的 301 要保留多久?

建议长期保留,至少一年,有条件就一直保留。旧域名的外部链接不会因为你换了域名就消失,只要旧域名还在解析,就应该继续把访问者送到新站。域名到期前记得续费——域名过期是唯一无法用 301 挽回的情况。

用 JavaScript 跳转能替代 301 吗?

不能。搜索引擎和 AI 爬虫在抓取阶段经常不执行 JavaScript,看到的是一个内容为空的页面;即使执行了,权重传递效果也远不如 301。JS 跳转只适合作为辅助手段,不能作为迁移方案。

只改文件名不改目录结构,也需要 301 吗?

需要。任何已发布地址的变化都算迁移,哪怕只是去掉了结尾的 .html。判断标准是"这个地址之前有没有对外出现过",而不是"改动大不大"。

迁移后引用掉了,还能恢复吗?

如果旧地址返回 301 并且新地址内容一致,引用通常会随着重新抓取逐步恢复,周期几周到几个月。如果旧地址返回 404,或者新地址内容被大改,恢复就很困难——这也说明迁移时要尽量保持内容主体不变。

小结

  • URL 变更的伤害滞后 2–6 周出现,别因为当天没问题就放心。
  • 每一条旧地址都要有 301,跳转链控制在一跳以内。
  • 新旧地址同时返回 200 是收益最差的做法。
  • nginx 里判断跳转要看 $request_uri,否则可能被内部改写拖进死循环。
  • 迁移后同步更新 sitemap、内链与 robots.txt,并把 301 保留一年以上。

迁移只是 GEO 工作里的一环,整体思路见《什么是 GEO》


如果你正在做站点迁移,拿不准某条跳转规则会不会出问题,欢迎到留言板贴出配置,一起看看。

站内搜索

没有找到内容!