换域名后重定向全坏了:修掉 404 并救回 SEO

从 old.com 迁到 new.com,Search Console 冒出数百个 404。如何建完整的 redirect map、部署在旧域名上、并验证每个 URL 都返回 301。

你从 old.com 迁到 new.com。配了 old.comnew.com 的重定向,测了首页,通的。两周后 Search Console 显示新域名上数百个 404、流量下降、外链全打不开。

最快的修复:你几乎肯定只重定向了,而不是每一条 URL 路径。只重定向根,会把 old.com/blog/article 跳到 new.com/(或一条已不存在的路径),于是 404。你需要的是一条保留路径的兜底规则,外加对那些结构变了的 URL 写显式规则,全部返回 301、全部部署在域名的托管上。跑一句 curl -sI "https://old.com/some-deep-url",看 Location: 响应头:如果它指向裸根或一条死路径,那就是你的 bug。

本文带你建一份完整的 redirect map,并在部署后验证。

你属于哪一类?

拿旧站一条真实的深 URL 跑一次 curl,看结果:

curl -sI https://old.com/blog/real-post 显示诊断跳到
301 + Location: https://new.com/(裸根)只重定向了根原因 1
301 + Location: https://new.com/blog/real-post,但新站这页 404URL 结构改了,map 没跟上原因 2
部分路径返回 200(根本没重定向)通配符/模式规则没匹配上原因 3、4
https:// 请求报 TLS/证书错误旧域名没有效证书原因 6
Connection refused / 超时旧托管彻底下线了原因 5

常见原因

按命中率从高到低。

1. 只重定向了根,深 URL 没处理

old.comnew.com 只重定向了裸根。old.com/blog/article-name 跟随重定向,落到 new.com/(多数域名转发规则会丢掉路径),或落到可能不存在的 new.com/blog/article-name。两种都是 404。

怎么判断:

curl -sI "https://old.com/some-deep-url" | head -3

如果看到 Location: https://new.com/,就是只重定向了根。应该是 Location: https://new.com/some-deep-url

2. URL 结构改了但 redirect map 没跟上

你在迁移时把 /blog/article-name 改成了 /articles/article-name。哪怕配了保留路径的完整重定向,请求还是落到新域名上的路径,于是 404。

**怎么判断:**看重定向目标。如果它保留了老路径,但新站没有老路径,你就得在重定向里加一段路径改写(见下面 Vercel/Netlify 示例里对应原因 2 的那条规则)。

3. 通配符 / 模式重定向无效

你写了模式重定向,但平台不支持那个语法,于是静默回退成无重定向。三大静态托管的捕获语法各不相同:Vercel 用 :slug:path*,Netlify 用 *:splat,Firebase 用 :slug* 这种 glob 捕获。把一个平台的规则直接复制粘贴到另一个平台,是静默失败的常见原因。

怎么判断:curl 一条本该匹配该模式的 URL。返回 200(而不是 301)就说明模式从没匹配上。

4. 托管平台有重定向数量上限(截至 2026 年 6 月)

静态托管对一个配置文件能放多少条重定向规则有上限:

平台文件上限(2026 年 6 月)超出后怎么办
Vercelvercel.jsonredirects1,024 条Bulk Redirects(每项目最多 1,000,000 条)或 Edge Middleware
Vercel每次部署的总路由数2,048 条路由把静态重定向搬到 Edge Middleware / Bulk Redirects
Netlify_redirects / netlify.toml无硬性条数上限;序列化输出过大则部署失败多用通配符/占位符;超过约 10,000 条 Netlify 建议这么做;复杂场景用 Edge Functions
Firebasefirebase.jsonredirects有实际 glob 规模上限用 glob 捕获,别一条 URL 写一条规则

修法几乎从来不是”再加规则”,而是把成百上千条 1:1 规则收成几条通配符捕获加一条兜底。

**怎么判断:**数你配置里的规则条数。Vercel 上 vercel.json 超过 1,024 条的那部分会被丢掉。

5. 旧域名托管彻底下线了

如果你彻底关停了 old.com 的托管(不只是改 DNS),重定向就永远发不出去。旧 URL 返回连接拒绝或超时,Google 也没法跟随一个不响应的重定向。

怎么判断:curl -I https://old.com/anything 报网络错误。你需要保留一个只做重定向的部署。

6. HTTPS 旧域名没证书

你配了 HTTP 重定向,但对 old.com 的 HTTPS 请求在重定向发出之前就因证书错误失败了。现代浏览器默认 HTTPS,而任何曾经发过 HSTS 响应头的域名,在 max-age 窗口内都会强制 HTTPS,于是 HTTP 版本根本到不了。

怎么判断:curl -I https://old.com/ 报证书错误,而 curl -I http://old.com/ 通。重定向主机必须为旧域名提供有效证书(DNS 指向 Vercel、Netlify、Firebase 后它们都会自动签发一张)。

最短修复路径

第 1 步:导出所有旧 URL

来源,大致按完整度排序:

  • old.com/sitemap.xml(如果旧站或某个归档仍在提供)
  • Search Console(旧域名仍验证过)→ Performance → Pages → Export
  • 旧托管的服务器访问日志(唯一能抓到那些 Google 从未收录、但用户仍在访问的 URL 的来源)
  • Wayback Machine 找未收录页面
  • 外链数据(Ahrefs、Majestic,或 Search Console 的 Links → Top linked pages)——这些正是你最需要保住链接权重的 URL

去重,合成一份路径清单。

第 2 步:建 redirect map

为每个旧 URL 决定目标:

  • 有直接对应——直接映射:old.com/blog/foonew.com/articles/foo
  • 没精确对应——重定向到最近的分类:old.com/topic-x/*new.com/category/x/
  • 真孤儿——只在万不得已时兜底到首页(首页重定向传递的链接权重远不如主题相关的目标,而且 Google 可能把大量”路径跳根”当成软 404)

用 CSV 把 map 保持可审查、可进版本控制:

old_path,new_path
/blog/article-name,/articles/article-name
/topics/ai,/category/ai
/old-broken-page,/

第 3 步:转成平台的 redirect 语法

具体规则在前,兜底在后——Vercel 和 Firebase 都按第一条匹配的规则执行,所以顺序重要。

Vercelvercel.json:slug 捕获一段,:path* 捕获剩余路径):

{
  "redirects": [
    { "source": "/blog/:slug", "destination": "https://new.com/articles/:slug", "permanent": true },
    { "source": "/topics/:topic", "destination": "https://new.com/category/:topic", "permanent": true },
    { "source": "/:path*", "destination": "https://new.com/:path*", "permanent": true }
  ]
}

"permanent": true 发出的是 308(保留请求方法的现代永久重定向);对站点迁移而言,Google 把 301308 同等对待。只有临时迁移才用 "permanent": false

Netlify_redirects* 做匹配,:splat 是捕获到的尾段;若有真实文件可能盖住规则,用 301! 强制):

/blog/*    https://new.com/articles/:splat    301!
/topics/*  https://new.com/category/:splat    301!
/*         https://new.com/:splat             301!

Firebasefirebase.json(glob 捕获用 :segment*):

{
  "hosting": {
    "redirects": [
      { "source": "/blog/:slug", "destination": "https://new.com/articles/:slug", "type": 301 },
      { "source": "/:path*", "destination": "https://new.com/:path*", "type": 301 }
    ]
  }
}

第 4 步:把重定向部署在域名的托管上

这步是大多数人漏掉的。让 old.com 的托管继续跑,里面只有重定向规则——你不需要整个 app,只要一个极小的静态部署,它唯一的活就是承载这份重定向配置。Vercel、Netlify、Firebase 都能 host 一个除了 vercel.json / _redirects / firebase.json 之外什么都没有的”站点”。

然后在旧域名上确认两件事:

  1. old.com(和 www.old.com)的 DNS 仍指向这个重定向主机。
  2. 重定向主机为旧域名持有有效 SSL 证书——否则会被原因 6 咬到。

第 5 步:用 curl 验证

随机抽 50+ 个旧 URL,确认每个都以永久重定向落到一个存在的新 URL:

while read -r url; do
  # -L 跟随重定向,-o /dev/null 丢掉响应体,再打印最终状态码 + 重定向跳数
  echo "$url -> $(curl -sIL -o /dev/null -w '%{http_code} via %{num_redirects} hop(s)' "$url")"
done < <(shuf old_urls.txt | head -50)

每行都应以 200 via 1 hop(s) 结尾(一次干净的 301/308 落到存在的页面)。要警惕:

  • ... via 2 hop(s) 或更多——重定向链(比如 http→https→新域名);把它压平,让旧 URL 一跳直达新 URL。
  • 最终 404——目标不存在;修 map 里那条。
  • 非根 URL 却重定向到 https://new.com/——又是原因 1。

第 6 步:在 Search Console 提交 Change of Address

域名的资源里:Settings → Change of address → Update,然后选新域名。截至 2026 年 6 月,该工具要求:

  • 旧域名和新域名都在 Search Console 里、用同一个 Google 账号验证。
  • 域名级资源(example.com,不是 example.com/path)。
  • 301 已经在跑——工具会做迁移前检查,关键项不过就拦下来。

Google 现在建议对旧域名的每一个变体都跑一次 Change of Address——www 和非 www,以及任何子域名——哪怕你没在用。该工具会告诉 Google 把排名信号从旧资源迁到新资源。

第 7 步:重定向留得比你想的更久

Google 自己的指引(2026 年 6 月)是:重定向至少保留 180 天,只要旧 URL 还在收到 Search 流量就更久。实际中外链能存在好几年,所以那个只做重定向的部署无限期留着。别在迁移”感觉做完”后就撤掉。

怎么确认修好了

  1. 第 5 步的 curl 循环里,每个抽到的 URL 都显示 200 via 1 hop(s)
  2. 在 Search Console(新域名)→ Indexing → Pages,“Not found (404)” 数量在几个抓取周期内停止攀升、随后下降。
  3. 域名资源里,Change of Address 横幅显示为进行中/已完成的迁移,而不是 “not started”。
  4. 在浏览器里抽查 5 条权重最高的外链——每条都应落到正确的新域名页面,而不是 404。

容易误判的情况

有人以为 Google “自己会”。没有显式 301,链接权重就丢了。当 URL 结构变了,Google 不会去猜 old.com/foo 等于 new.com/foo——它需要重定向把两者连起来。一堆首页重定向也是个坑:Google 可能把”路径跳根”当软 404 丢弃,所以只要存在主题相关的对应页,就映射过去。

预防建议

  • 在新域名上线就建好 redirect map,别当成事后清理。
  • 重定向规则进版本控制(vercel.json_redirectsfirebase.json)。
  • 旧域名的重定向部署无限期保留,永远别撤。
  • 每次部署后,用上面那段 curl 循环抽测 50+ 条重定向。
  • 大站从一开始就围绕通配符捕获设计 map,这样既守住平台规则上限(Vercel 的 1,024 条),也避免重定向链。

FAQ

  • 重定向要保留多久? Google 说至少 180 天,只要旧 URL 还在收到 Search 流量就更久。因为外链能活过这个窗口,建议无限期保留。
  • 永久迁移用 301 还是 302? 用永久重定向(301,或 Vercel "permanent": true 发出的 308)。302/307 是临时的,会让 Google 继续收录旧 URL,排名信号传不全。
  • 真有必要让旧域名的托管一直活着吗? 有。重定向只有在旧域名上有服务器、且持有效证书并响应时才会触发。彻底关停旧主机,每条旧 URL——以及指向它的每条外链——都会失效。
  • 我的站有 5 万条 URL,撞到了 Vercel 的 1,024 上限,怎么办? 把 1:1 规则收成通配符捕获(/blog/:slug 一条就覆盖所有博文)。对实在不规则的映射,用 Vercel Bulk Redirects(每项目最多 1,000,000 条)或写一段从列表里查目标的 Edge Middleware。
  • 查询参数和结尾斜杠会跟着重定向保留吗? 不会自动保留。Vercel 和 Netlify 默认保留查询字符串,但结尾斜杠的行为要你自己对齐;在 curl 抽样里把 /blog/foo/blog/foo/ 都测一遍。

相关阅读

标签: #域名 #DNS #SSL #排查 #重定向