做站点审计时经常碰到这样一个页面:HTML 里写了 meta robots,HTTP 响应头里还挂着一个 X-Robots-Tag,head 里放了 canonical,页面上某个链接又加了 rel="nofollow"。这些标签单独看都没问题,放在一起却可能互相打架。想改对,得先知道它们各自管什么。
先分清:三类指令不在同一个层面
很多所谓的冲突,其实是误以为它们在管同一件事。实际上它们作用在收录流程的不同阶段:
- 抓取层:robots.txt 的 Disallow,以及链接上的 rel="nofollow"、rel="sponsored",影响的是蜘蛛要不要去取这个 URL。
- 索引层:meta robots 的 noindex、X-Robots-Tag: noindex,影响的是取回来之后要不要放进索引。
- 规范化层:rel="canonical"、301 跳转,影响的是这份内容算在哪个地址名下。
三个阶段不同,所以它们可以同时生效,也就会出现方向相反的组合。
几种常见的方向相反组合
noindex 和 canonical 同时出现
这是最典型的一种。noindex 说别收录我,canonical 说我的内容属于另一个地址。两个信号互相抵消,搜索引擎只能自己挑一个处理,结果往往不稳定。如果本意只是想把信号集中到主版本,只用 canonical 就够了;再加一个 noindex,可能连“内容归属”这条信息也一并丢掉。
noindex 和 nofollow 一起用
页面本身已经不打算进索引,页面里的链接再加 nofollow 通常意义不大。除非你确实不希望蜘蛛顺着这些链接继续往下一层爬,否则这一步可以直接省掉,也能减少以后排查时的心智负担。
canonical 指向一个 noindex 的页面
源页面说“我的内容算在 A 名下”,A 自己却说“别收录我”,等于把内容指向了一个黑洞。批量生成 canonical 时特别容易踩到:模板统一指向某个列表页或参数页,而那个页面恰好被设成了 noindex。
robots.txt 挡住,同时又依赖页面里的标签
robots.txt 挡的是抓取。蜘蛛拿不到页面内容,自然也读不到里面的 meta robots 和 canonical。所以被 Disallow 的 URL 仍有可能出现在索引里,只是没有摘要。想让一个地址彻底退出,robots.txt 不是一个合适的工具。
冲突时的大致判断顺序
- 能抓取是一切前提:robots.txt 挡住之后,页面级指令根本读不到,讨论优先级没有意义。
- noindex 比 canonical 更硬:canonical 更接近提示,noindex 更接近指令,方向上通常取更保守的那个结果。
- 同一层面的信号冲突时,一般按更严格的一方处理,比如响应头只禁止索引、页面里禁止索引且禁止跟随,最终多半按后者走。
- 别把“谁赢”当成设计手段。靠故意制造冲突来达到某种效果,结果往往不可预期。
X-Robots-Tag 与 meta robots 的分工
一个在 HTTP 响应头,一个在 HTML 里。对 HTML 页面来说作用接近,冲突时通常按更严格的处理。X-Robots-Tag 的真正价值在于非 HTML 资源——PDF、图片、音视频这些没有 head 的文件,只能靠响应头来传达指令。
上线前可以照着做的检查
- 用 curl -I 看响应头,确认有没有意外的 X-Robots-Tag。
- 查看页面源码里的 meta robots 和 canonical,注意 canonical 写的是绝对地址还是相对地址。
- 打开 robots.txt,确认目标 URL 没有被 Disallow 覆盖。
- 顺着 canonical 指向的那个地址再看一遍,它自己是不是也带着 noindex 或被 robots.txt 挡住。
- 检查站内导航和正文链接上有没有多余的 nofollow,这类位置通常不该出现它。
指令冲突不会报错,只会让结果变得难以预测。宁可少加,也不要给同一个 URL 挂上方向相反的两个信号。
更省事的做法:先给每个 URL 定一个目标
在动手加标签之前,先回答三个问题:这个 URL 要不要被蜘蛛抓到?抓到之后要不要进索引?它的内容和哪个地址是同一份?三个问题答完,需要哪些指令基本就清楚了。多数冲突都来自“为了保险全都加上”这种习惯。
上线之后最好再验证一次:用抓取工具或服务器日志确认实际返回的响应头和 HTML,跟预期一致。模板、CDN 或反向代理都可能在部署环节覆盖掉你写的标签,而这一层往往是最容易被忽略的地方。