你买了 yourbrand.com,又”以防万一”买了 yourbrand.net,两个返回的内容一模一样。AdSense 审核不通过,或者站点在 “Getting ready” / “Needs attention” 里挂了好几周。审核员看到两份一样的站,分不清哪个是真的。在 2026 年,这种情况通常表现为 “Low value content” 拒绝,子原因是 “Copied or duplicate content”,而不是一句友好的”你已经有这个站了”。
最快的修法: 选一个 canonical 域名,把其它所有域名都 301 重定向过去,确认备用域名返回的是 301(不是 200),然后在 AdSense 对 canonical 请求审核。别去把重复的站改”独特”,也别把每个变体都加进 AdSense Sites。
这条同样适用于 apex/www 拆分、.com/.net/.org 一整套、被收录的 staging 子域名,以及改名后没 301 的旧域名。
你属于哪一类?
| 现象 | 大概的原因 | 跳到 |
|---|---|---|
两个以上根域名都返回 200 | 防御性备用域名也在服务 | 原因 1 |
| 改名后旧品牌还能打开 | 改名了但旧域名还在服务 | 原因 2 |
www 和 apex 都能打开页面 | www/apex 没做重定向 | 原因 3 |
Google 里搜得到 staging. | staging 被公开收录 | 原因 4 |
Google 里出现 *.vercel.app / *.netlify.app | 预览部署被收录 | 原因 5 |
| AdSense 一直拒同一个根域名 | 另一个根域名在服务相同内容 | 原因 6 |
常见原因
按命中率从高到低。
1. 防御性备用域名也在服务
为防身买了 yourbrand.net 和 .org,都指向同一套托管。于是它们全都能访问、返回一样的页面,AdSense(和 Google)就看到了好几个内容一模一样的 property。
怎么判断:
for d in yourbrand.com yourbrand.net yourbrand.org; do
echo -n "$d: "
curl -sI "https://$d" | head -1
done
如果都返回 200(而不是 301 到 canonical),就是重复。
2. 改名后旧域名还在服务
从 oldbrand.com 改名到 newbrand.com。新站上线了,但旧 DNS 还指着托管,旧域名还在用旧 URL 返回内容。
怎么判断: curl -sI https://oldbrand.com。返回 200 就是没真改完,应该是 301 到 newbrand.com。
3. www 和 apex 各自独立服务
www.yourdomain.com 和 yourdomain.com 都能解析、都返回页面。Google 可能两个都收录,互相当成重复在竞争。
怎么判断:
curl -sI https://yourdomain.com | head -3
curl -sI https://www.yourdomain.com | head -3
其中一个应该 301 到另一个(哪个当 canonical 你自己定)。
4. staging 子域名被公开收录
你有个 staging.yourdomain.com 做 QA,没设 auth。Google 找到了、收录了,于是它就成了生产环境的重复。
怎么判断: Google 搜 site:staging.yourdomain.com。有结果就是 staging 被公开收录了。
5. Vercel / Netlify 预览部署被收录
先说结论:默认情况下这基本不是问题。截至 2026 年 6 月,Vercel 会自动给 *.vercel.app 预览部署加 X-Robots-Tag: noindex,Netlify 也会给 Deploy Preview、未发布的部署以及较旧的 branch deploy 加 X-Robots-Tag: noindex。真正的坑是 Vercel 上把自定义域名挂到了非生产分支 —— 只有这一种情况,Vercel 不会加 noindex 头,预览就能被爬。
怎么判断: Google 搜 site:vercel.app yourbrand 和 site:netlify.app yourbrand,再直接确认响应头:
curl -sI https://yourapp-git-feature-yourteam.vercel.app | grep -i x-robots-tag
如果 x-robots-tag: noindex 不在(一般只会发生在自定义域名挂预览分支的情况),就需要手动补上。
6. AdSense Sites 里两条指向相同内容
变的就是这一条。AdSense 的站点管理现在按域名(根域)级别操作 —— 你已经不能再把 www.yourdomain.com、https://yourdomain.com/、带尾斜杠的变体或任意子域名当作独立的 Sites 条目加进去了。AdSense 只接受可注册的根域(比如 yourbrand.com、yourbrand.net)。所以现在的重复问题不是变体条目,而是加了两个真正不同的根域名(yourbrand.com 和 yourbrand.net)却服务同一批页面。
怎么判断: AdSense → Sites。如果列了两个根域名、两个都返回相同内容,那就是你的重复信号。
最短修复路径
第 1 步:选定一个 canonical 域名
通常选最短、最常对外宣传的、或最老的版本。常见选择:
yourbrand.com(你实际在推广的.com)www.yourbrand.com,如果 SSL 或 CDN 配置更适配 www- apex(裸域),如果你的 CDN 在根支持
ALIAS/ANAME
定一个就别再纠结。找个显眼的地方写下来(仓库里放个 CANONICAL_DOMAIN.md 就行),免得未来自己又来回改。
第 2 步:所有其它域名 301 到 canonical
301(永久)是 Google 支持的最强 canonical 信号 —— 比 rel="canonical" 标签更强 —— 所以只要用户不需要直接访问那个备用 URL,就优先用 301。
Cloudflare — Rules → Redirect Rules(较新的界面;老账号 Page Rules 仍然能用):
If: hostname equals yourbrand.net
Then: Static redirect to https://yourbrand.com${path}${query}
Status: 301 (permanent)
Vercel — 在备用域名所在项目的 vercel.json:
{
"redirects": [
{ "source": "/:path*", "destination": "https://yourbrand.com/:path*", "permanent": true }
]
}
"permanent": true 发的是 308(Google 等同于 301 处理);只有在确实需要临时跳转时才用 "permanent": false。只配在备用域名的项目上 —— canonical 项目不加任何重定向。
Netlify — 在备用站点的 _redirects:
https://yourbrand.net/* https://yourbrand.com/:splat 301!
结尾的 !(“强制”)让规则即使存在匹配的文件也照样生效。
第 3 步:别让 staging 和预览进入索引
staging —— 最好用 basic auth 挡住;或者用 robots.txt 拦爬,再配一个响应头:
User-agent: *
Disallow: /
robots.txt 只能阻止抓取,并不能阻止已知 URL 被收录,所以每页还要发真正的 noindex。响应头是最可靠的形式:
X-Robots-Tag: noindex
在 HTML 里对应的是每页一个静态标签(不需要框架的条件渲染):
<meta name="robots" content="noindex">
预览 —— Vercel/Netlify 的默认行为别动,它们已经在发 X-Robots-Tag: noindex 了。唯一要修的是 Vercel 自定义域名挂在预览分支 的情况,它会丢掉自动加的头。在 vercel.json 里补回来:
{
"headers": [
{ "source": "/(.*)", "headers": [{ "key": "X-Robots-Tag", "value": "noindex" }] }
]
}
只对预览项目配这个 —— 永远别把 noindex 发到生产。
第 4 步:AdSense Sites 每个真实站点只留一个根域名
AdSense → Sites。因为现在是按域名级别管理,这里一般不会出现 www/https/尾斜杠这类变体。可能出现的是两个真实的根域名。备用域名(yourbrand.net、.org)一旦 301 到 canonical 就把它从这里移除,只保留你真正在变现的那个域名。
第 5 步:用 curl 验证重定向
for d in yourbrand.net yourbrand.org www.yourbrand.com staging.yourbrand.com; do
echo "=== $d ==="
curl -sI "https://$d" | head -3
done
每个都应返回 HTTP/2 301(Vercel 是 308),并带一个指向 https://yourbrand.com/... 的 location: 头。一个常见错误是路径被丢掉的”裸跳转”(所有页面都落到首页)—— 确认 https://yourbrand.net/some/article 会落到 https://yourbrand.com/some/article。
第 6 步:确认 Google 选的 canonical,然后等
Google 要重新爬每一个重复并跟随 301,这要花上几周。在 Search Console 里加速:
- URL 检查 → 输入你的 canonical URL。
- 看 “Google-selected canonical”(Google 选定的规范网址)字段 —— 应该和你的 canonical 一致。
- 如果显示的是某个重复,点 Request Indexing(请求编入索引),再检查几个备用 URL,确认它们报的是 “Page with redirect”(含重定向的网页)。
小站合并大概要 2-4 周(截至 2026 年 6 月);大站更久。
第 7 步:在 AdSense 对 canonical 请求审核
301 都设好、Search Console 也显示了正确的 canonical 之后,到 AdSense → Sites 对 canonical 那一条请求审核。如果之前的拒绝理由是 “Low value content / Copied or duplicate content”,它等的就是这次改动。
怎么确认修好了
- 对每个备用域名
curl -sI都返回301/308,且location:保留路径。 - 重新爬过之后,
site:yourbrand.net和site:staging.yourbrand.com搜不到结果(或只剩 canonical)。 - 抽查的页面在 Search Console 里的 “Google-selected canonical” 等于你的 canonical。
- AdSense → Sites 里每个真正不同的站点正好一条,状态都是 Ready。
哪些情况可能不是你操作错了
哪怕 301 都设好、AdSense 也只剩一条,审核队列还是可能滞后。AdSense 是在下一次爬取时才检测到合并,不是即时的,所以一个改对了的站也可能还显示几周的 “Needs attention”。如果 curl、Search Console 的 canonical、Sites 列表三项都没问题,你这边就到位了 —— 等重新爬完再说,别再瞎改。
容易误判的情况
有人把所有变体都加进去”覆盖全部”,结果适得其反:这是在告诉 Google 你这一个站其实是好几个内容一模一样的 property,反而喂大了重复内容信号。保持最小化 —— 一个 canonical 域名,其余全部 301,每个真正不同的站点在 AdSense Sites 里只留一条。
预防建议
- 第一天就选定 canonical 域名,找个显眼的地方写下来。
- 发第一篇文章之前,先设好
www → apex(或反过来)的重定向。 - Vercel/Netlify 预览的默认行为保持原样,只修 Vercel 自定义域名挂预览分支这一种情况。
- staging 用 auth 挡住,或者
noindex+robots.txt拦掉。 - 防御性域名(
.net、.org、易错拼写)第一天就 301,永远不要让它们直接返回内容。
FAQ
- 一个 AdSense 账号能变现多个域名吗? 能,前提是各自有真正独立的内容。同一个账号下一个电影站、一个菜谱站没问题;两个域名服务同一批文章则不行。
- 用 301 还是
rel="canonical"? 用户不需要访问备用 URL 时(也就是这里的情况)用301。只有当两个 URL 都必须保留可访问(比如带筛选参数或打印版的页面)才用rel="canonical"。 - Google 会取消收录重复吗? 设好 301 之后,Google 会把备用域名从索引里去掉,并把链接权重合并到 canonical,排名也随之转移。
- AdSense 已经以”duplicate content”拒了我,是重新申请还是等? 先把 301 修好、确认 Search Console 的 canonical,再请求审核。重定向还没生效就重申,只会拿到一样的拒绝。
- 我的 Vercel 预览没改过任何东西,却进了 Google,为什么? 几乎都是把自定义域名挂到了非生产分支 —— 这是 Vercel 唯一会跳过自动
X-Robots-Tag: noindex的情况。把这个头补回来(第 3 步)。