做站点审計时经常碰到這样一個頁面: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 或反向代理都可能在部署环节覆盖掉你寫的标簽,而這一层往往是最容易被忽略的地方。