www 与 non-www 都能独立打开

yourdomain.com 和 www.yourdomain.com 都返回 200、内容一模一样——为什么这会分散 SEO 信号,以及各家主机上精确的 301 修法。

你输入 https://yourdomain.com,站点打开。再输入 https://www.yourdomain.com,同一个站也打开、内容一模一样。两个都返回 200。看着没问题,但对 Google 的去重机制、以及任何统计你外链的工具来说,你其实有两个内容相同的站在互相争夺权重。

最快的修法:选一个主机名作为 canonical,让另一个在主机/CDN 层返回 301 重定向到它(不是只加一个 HTML <link rel="canonical"> 标签)。canonical 标签只是告诉爬虫你的偏好;301 才真正把访客和外链权重收拢到一个 URL 上。一条命令确认是否修好:

curl -sI https://www.yourdomain.com | grep -i -E "http|location"

你想看到 301 以及一个指向 canonical 主机的 Location: 头。如果看到的是 200,说明重定向还没生效。

这是 www vs root redirect 的更难版本:那篇里有一个版本根本打不开;这里两个都能正常工作,所以接好重定向之后你还得清理收录和外链。

为什么这真的重要(不是表面问题)

yourdomain.comwww.yourdomain.com 是不同的主机名,所以除非你明确告诉搜索引擎,它们会被当成不同的 URL。没有 301 时:

  • 外链被分到两个主机上,哪个都攒不满权重。
  • Google 会自己挑一个 canonical(不一定是你想要的那个——见 Google 的 canonicalization 排查指南),Search Console 里的报表也会变乱。
  • 分析统计、cookie、以及任何同源登录在两个主机之间可能表现不一致。

你属于哪一种情况?

先跑下面两条 curl,再对照原因。

你观察到的现象最可能的原因在哪修
两个主机都直接从你的主机返回 200两个都作为独立域名加了,没配重定向主机控制台(Vercel / Netlify / Firebase)
两个都 200,服务器在 Cloudflare 后面(已代理)两条 DNS 记录都代理了,没配重定向规则Cloudflare Redirect Rules
两个都 200,HTML 里有 canonical 标签设了 canonical 标签但没有 HTTP 301在主机/CDN 层加 301
两个都 200,自托管一个 nginx/Apache server_name 同时服务两个加一个重定向 server block
一个返回 301,另一个 200重定向已正确——把收录清理做完即可Search Console + 内链

诊断命令:

curl -sI https://yourdomain.com | head -5
curl -sI https://www.yourdomain.com | head -5

两个都是 HTTP/2 200 表示没有重定向。其中一个是 HTTP/2 301 并带 Location: 头,说明那一侧已经在重定向了。

常见原因

按命中率从高到低。

1. 主机里加了两个版本但没配重定向

你在 Vercel/Netlify 把 yourdomain.comwww.yourdomain.com 当成两个独立域名都加了。主机乐意都服务,默认不配重定向。

怎么判断:主机控制台 → Domains → 两个看起来都是对等的 “primary” 项。你需要的是恰好一个 primary、一个 redirect。

2. CDN 把两者都直接代理到源站

如果 Cloudflare(或别的 CDN)把两条 A/AAAA/CNAME 记录都设了代理,两个都到达源站、都返回内容。除非你加规则,CDN 不会重定向。

怎么判断:上面两条 curl -sI 都返回 200。在 Cloudflare 的 DNS 标签页里,两条记录都显示橙色 “Proxied” 云朵。

3. 主机支持两个绑定但不会替你推断 primary

有些主机允许你加两个名字,但要求你手动选 primary,不会替你假设要哪个。

怎么判断:主机文档写着”加两个,然后设其中一个为 primary”——而你加完两个就停了。

4. 设了 canonical 标签但没有 HTTP 重定向

你给每一页都加了 <link rel="canonical" href="https://yourdomain.com/...">。标签是给 Google 的提示,但访客还是看到他们输入的那个主机,原始外链也还是指向非 canonical 主机。

怎么判断:两个 URL 都返回 200(不是 301)。canonical 标签从不重定向。

5. 自托管 nginx/Apache 同时服务两个名字

老的共享主机或手写配置里,可能有一个 server_name yourdomain.com www.yourdomain.com; block 而没有重定向规则。两个名字都能用,于是产生重复内容问题。

怎么判断:SSH 进去看配置。如果 server_name 在同一个 block 里列了两个名字、且没有单独的重定向 server block,就是这条。

最短修复路径

第 1 步:选 canonical 主机

两个选择对 SEO 都中性——Google 已确认排名上没有差别。按技术因素来选:

  • Apexyourdomain.com):URL 更短,前提是你的 DNS 提供商在 apex 上支持 ALIAS/ANAME/CNAME 扁平化。DNS 规范禁止在 apex 记录上用普通 CNAME,这也是有些主机引导你用 www 的原因。
  • wwwwww.yourdomain.com):CDN 配置最省事,因为 www 是普通子域、可以用普通 CNAME。截至 2026 年 6 月,Vercel 明确建议把 www 设为 primary,正是出于这个原因(CDN 对进站流量有更多掌控)。

定好一次,写下来,并让所有内链、sitemap 条目和 canonical 标签都跟它保持一致。

第 2 步:在主机/CDN 层配重定向

Vercel — Project → Settings → Domains

  • yourdomain.comwww.yourdomain.com 都加上(加 apex 时会自动建议加上对应的 www)。
  • 非 canonical 那个域名上点 Edit,打开 Redirect to 下拉,选 canonical 主机。
  • Vercel 自动签发一个 308/301 级别的永久重定向。(Vercel 默认用 308,它保留请求方法,搜索引擎对它和 301 一视同仁地当作永久重定向。)

Netlify — Site configuration → Domain management → Domains

  • 加两个名字。
  • 把 canonical 那个设为 primary domain,另一个成为 domain alias。
  • Netlify 自动把 alias 重定向到 primary。这种自动行为只覆盖 apex ↔ www;其他子域要手动配重定向规则。

Firebase Hosting — 在控制台里加第二个域名时,选 “Redirect to an existing site/domain”(重定向到已有站点/域名)并指向 canonical。若要走配置即代码,在非 canonical 站点的 firebase.json 里设一条 catch-all 重定向,然后用 firebase deploy --only hosting 部署:

{
  "hosting": {
    "redirects": [
      { "source": "**", "destination": "https://yourdomain.com", "type": 301 }
    ]
  }
}

Cloudflare — Page Rules 已是旧功能,用 Redirect Rules。控制台路径:Rules → Templates → “Redirect from WWW to Root”(或 “Redirect from Root to WWW”)→ Create a Rule。要手动建的话,进 Rules → Redirect Rules → Create rule,用通配符:

When incoming requests match:  https://www.yourdomain.com/*
Then redirect to URL (dynamic): https://yourdomain.com/${1}
Status code:                    301
Preserve query string:         On

注意现在的占位符是 ${1}(旧的 Page Rules 用的是 $1)。部署规则,并保持对应的 DNS 记录处于代理状态(橙色云朵),规则才会实际生效。

自托管 nginx — 把重定向拆成单独的 server block:

server {
    listen 443 ssl;
    server_name www.yourdomain.com;
    return 301 https://yourdomain.com$request_uri;
}

然后用 nginx -t && systemctl reload nginx 重载。Apache 对应做法:在 www 的 VirtualHost 里用一条 Redirect 301 / mod_rewrite 规则。

第 3 步:验证重定向

curl -sI https://www.yourdomain.com | head -5

你想看到:

HTTP/2 301
location: https://yourdomain.com/

Vercel 返回的 308 也是对的。返回 200 就是重定向还没上线。再测一个深层路径,确认重定向会保留路径、而不只对首页生效:

curl -sI https://www.yourdomain.com/some-article/ | grep -i location
# 预期:location: https://yourdomain.com/some-article/

第 4 步:让 HTML canonical 标签保持一致

模板里的 canonical 必须在每一页都指向 canonical 主机:

<link rel="canonical" href="https://yourdomain.com/your-article/" />

绝不能指向 alternative 主机。重定向加一个相矛盾的 canonical 标签,会发出互相打架的信号。

第 5 步:修 Search Console(现代做法)

如果你把两个主机当成两个独立的 URL-prefix property 验证过,最干净的修法是给 yourdomain.com 加一个 Domain property。Domain property 会自动把 http/https、www、non-www 以及所有子域合并进一份统一报表,你就不用再跨两个 property 拼数据了。用 Google 给的 DNS TXT 记录验证一次即可。

旧的 URL-prefix property 想留就留(盯非 canonical 主机的索引下降很方便),但把 canonical 主机当作 primary。

第 6 步:确认 Google 选对了 canonical

打开 Search Console → URL Inspection,粘贴一个非 canonical 的 URL(例如 https://www.yourdomain.com/your-article/),看 “User-declared canonical”“Google-selected canonical” 是否一致。301 被爬到之后,Google-selected 应收敛到你的 canonical 主机。Google 明确说过它可能选一个跟你声明不同的 canonical,所以这一步才是真正的证据——光看重定向不够。

合并是渐进的:大约 2–4 周内 Google 会重新抓取并把链接权重转到 canonical 上。在 Search Console → Indexing → Pages 里,非 canonical 的 URL 应逐步落入 “Alternate page with proper canonical tag” / “Page with redirect” 这些分类。

如何确认彻底修好了

  1. 对非 canonical 主机跑 curl -sI 返回 301/308,且 Location: 正确(首页一个深层路径都要测)。
  2. canonical 主机直接返回 200(它不能重定向到自己——那会形成死循环)。
  3. URL Inspection 显示 Google-selected canonical = 你选定的主机。
  4. 2–4 周内,被收录的非 canonical URL 趋向归零。

哪些情况不是你操作错了

确实有几个主机的怪癖:Firebase 的逐站点模型、Cloudflare 的 apex-vs-subdomain 代理处理、以及在 apex 上不支持 ALIAS/ANAME 的 DNS 提供商。如果主机的行为跟它自己的文档矛盾,附上你的 curl -sI 输出提工单。

容易误判的情况

只加 <link rel="canonical"> 标签并不能阻止双服务——两个主机仍然都回 200。只有主机/CDN 层的 301/308 才能把真实流量和外链收拢。如果你”加了 canonical 标签”但两个 URL 还都能打开,说明修复没做完。

预防建议

  • 任何新域名第一天就决定 www vs apex。
  • 永远在主机/CDN 层做重定向,而不只是加 canonical 标签。
  • 任何 DNS 或主机变更之后,用 curl -sI 重新确认一个主机 301 到另一个。
  • 一开始就用单个 Search Console Domain property,让合并自动完成。
  • 团队管理的域名,在 DOMAIN.md 里记下 canonical 选择。

FAQ

  • www 还是 apex 对 SEO 更好? 排名没差别,Google 直接说过。按技术因素选(apex 需要 ALIAS/ANAME;www 用普通 CNAME 即可)。
  • 我的主机返回 308 而不是 301,是不是错了? 不是。308 是永久重定向,还会保留 HTTP 方法。Vercel 默认用它,搜索引擎在合并上把它等同于 301
  • 301 已经上线了,还需要 canonical 标签吗? 需要。301 处理打到错误主机的访客和爬虫;canonical 标签强化你的选择,并覆盖带参数 URL 这类边角情况。
  • Google 多久才合并? 通常是 2–4 周的重新抓取。盯 URL Inspection 里的 Google-selected canonical,别靠猜。
  • 以后能改 canonical 吗? 能,但意味着一条重定向链(老 canonical → 新 canonical)、canonical 标签更新、以及 4–8 周让 Google 完全切换。别随便切。
  • 两个已经互相重定向、站却挂了,为什么? 你做出了重定向死循环(每个主机都指向对方)。canonical 主机必须返回 200,只能由非 canonical 主机做 301

相关阅读

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