站内出现重复内容时,canonical 是最常用的收口手段:把几个相似的 URL 都指向同一个主版本,让搜索引擎知道该保留哪一个。但很多人只检查了「指向对不对」,忽略了另一半——被指向的那个 URL 本身能不能被抓取、能不能进索引。如果目标页自己就进不去,收口链条其实是断的。
canonical 是提示,不是指令
先建立合理预期:canonical 属于建议性信号,搜索引擎会参考,也可能忽略,它会结合内链、站点地图、内容相似度、外部链接等一起判断。所以写对了不保证一定按你的设想收口;但如果写错了,或者指向的目标页存在硬性障碍,那基本不会按你的设想收口。
几个常见的断点
目标 URL 被 robots.txt 屏蔽或自带 noindex
这是最典型的一种。页面 A 的 canonical 指向页面 B,而 B 恰好被 robots.txt 禁止抓取,或者 B 自己带了 noindex。结果是 B 不会被索引,A 又明确声明自己不是主版本,两边信号互相抵消,最后可能两个 URL 都不出现在索引里。要作为收口目标的页面,首先得是「允许被抓取、允许被索引」的页面。
目标 URL 不可访问或已经跳转
canonical 指向一个 404、410 或返回 200 但内容为空的页面,信号都会被削弱。指向一个会 301 的中间地址也容易出错:你以为最终会落在 C,但 canonical 写的是 B,等于多绕了一层,还可能在后续改版中再次断掉。规范做法是直接指向最终可访问、长期稳定的那个 URL。
链式与环状 canonical
A 指向 B,B 指向 C,C 又指回 A,这类链条会让判断变得混乱。原则上应该是「多对一」:所有变体直接指向同一个主版本,而不是一个指一个。链式 canonical 在批量改版、模板层层套用的站点里很常见,值得专门抽查一遍。
跨域 canonical 指向自己控制不了的页面
把站内页面 canonical 到另一个域名,相当于主动把收录让出去。如果目标站之后改版、下线或给页面加了 noindex,你这边没有任何控制权。除非确实存在转载授权关系,并且能长期协调,否则不建议这么做。
canonical 与内链、站点地图、hreflang 说法不一致
内链大量指向变体 URL、站点地图里同时提交了变体和主版本、hreflang 又把某个变体当成独立语言版本——这些信号会和 canonical 打架。收口不只是加一个标签,还要让站内其他地方的表述统一起来,否则每个信号都在往不同方向拉。
一条可执行的排查顺序
- 取出页面上写死的 canonical,确认是绝对 URL,且指向的是最终版本而不是中间版本。
- 打开目标 URL,确认返回 200,内容与来源页属于同一主题或本身就是同一内容。
- 检查目标 URL 是否被 robots.txt 屏蔽、是否带 noindex、是否存在 meta refresh 或纯 JS 跳转。
- 查看目标 URL 自己的 canonical 指向哪里,顺着链条一直走到头,确认没有环。
- 对照站点地图、内链、hreflang 的写法,看是否与 canonical 保持一致。
日常维护的几个习惯
- 主版本 URL 一旦确定,尽量长期不换;确实要换时,同步修改所有指向它的 canonical。
- 模板层慎用「自动取当前 URL」的 canonical 写法,容易把带参数的变体也当主版本。
- 栏目合并或改版之后,抽查几条收口链条是否还能走通。
- 关注服务器日志和覆盖率报告,看被 canonical 收掉的 URL 是否出现异常堆积。
收口的目标不是「少几个 URL」,而是让该被索引的那个版本稳定地被索引。指向的目标页自己进不去索引,收口就等于没做。
如果排查收录时发现某个变体长期不消失,或者主版本反而没进索引,先别急着改内容,从 canonical 指向的目标页开始往下查,通常能更快定位问题。