我们发现大量主题永久链接(topic-permalink)和分页 URL 出现在 Google 搜索控制台的“已抓取 - 当前未编入索引”(Crawled - currently not indexed)类别中(在一个约 20 年前导入的论坛中,涉及约 35k 个 URL,Discourse 版本为 v2026.9.0-latest,自托管)。
我们的发现:
对于长主题,Discourse 会向爬虫提供 ?page=N 分页链接(因为真实 UI 使用无限滚动)。当支持 JavaScript 的客户端(包括 Googlebot 的渲染器)加载这些 ?page=N URL 时,Discourse 会发出客户端重定向,指向 /t/slug//<post_number>。
复现步骤:
- 冷启动获取带有任意帖子编号或 ?page= 后缀的主题 URL:
GET /t///14 →
GET /t// → 相同的规范链接(canonical)
GET /t///1 → 相同的规范链接
GET /t//?page=127 → (自引用,未规范化) - 正常加载站点(启用 JS),并通过 Ember 路由导航到包含帖子编号后缀的 URL(例如,从“建议主题”中点击“跳转到第一个未读帖子”链接)。一旦 SPA 过渡完成,document.querySelector(‘link[rel=canonical]’).href 等于当前的帖子编号 URL——它并未指回基础主题。
这与 Discourse 自身声明的设计意图相矛盾。在这个 2015 年的帖子中,@sam 明确表示:
▎ 主题:规范链接应指向基础主题,以防止单个帖子页面作为独立的搜索结果出现。
▎ 分类/列表页面:完全移除规范链接,因为根据 Google 自己的指南,分页列表并不属于重复内容。
我们今天观察到的情况在两个方面破坏了这一设计:
- 带有 ?page=N(爬虫分页)的主题,在原始服务器 HTML 中返回的是分页 URL 作为规范链接,而不是基础主题——尽管主题(与分类列表不同)明确应该始终折叠为基础 URL。
- 从 ?page=N 客户端重定向到 /t/slug/id/<post_number> 后,渲染后的 DOM 中的规范链接仍然保留在该帖子编号 URL 上,而不是重置为基础主题。
这两者看起来都是相对于 2015 年设计目标的回归(regression),而非当前有意为之的行为。
这对索引为何重要:Google 的索引系统依赖渲染后的 DOM 来获取规范链接信号。任何 Google 直接到达的带有帖子编号/页面后缀的 URL——通过“分享帖子链接”功能(在我们的论坛中通过 WhatsApp/Discord 大量使用)、通过旧的外部反向链接(我们正在将遗留的 vBulletin ?p= 永久链接映射到帖子编号 URL),或者通过爬虫自身——都会声明自己的规范链接,而不是合并到基础主题中。在搜索控制台中,这表现为数千个近乎重复的 URL 卡在“已抓取 - 未编入索引”状态。
来自我们 GSC 报告的受影响 URL 示例(全部在 2026 年 9 月初最后被抓取):
/t/tengo-que-pasar-la-itv/21100/10
/t/new-honda-nsx-proyect/4910/69
/t/hacer-tubo-recto-sin-silencioso-del-catalizador-hacia-atras/25579/25
/t/kedada-japo-en-cataluna-2014/28148/75
/t/el-diario-de-patricio-de-la-plana/13286?p
给团队的问题:鉴于这是一个超过 10 年的问题,是否有什么变化使得在这些 URL 上使用自引用规范链接现在是有意为之的?还是说这值得作为回归问题重新审视?如有需要,我很乐意提供 HAR 文件/更多复现示例。