摘要

  • 8 月 31 日,AFRINIC 的 News & Announcements 路由返回 HTTP 200,浏览器标题、页面 H1、2026 年新闻列表和 JSON-LD 都把它识别为新闻页。
  • 同一份响应中的 canonical、普通描述、Open Graph 标题与网址,以及 Twitter 标题,却把对象识别成另一张“Privacy Policy”页面。
  • AFRINIC 自己的 sitemap 分别列出 /news 和 /privacy。RFC 6596 要求 canonical 目标是重复内容或其超集,两张页面的实际角色并不符合这个关系。
  • 已证实的是源页面身份冲突,不是搜索降权、流量损失或某个平台已经展示错误卡片。最小控制是给每条公开路由留下一份可版本化的身份回执。

第一张身份证:人看到的是新闻

在 8 月 31 日 05:46 UTC 的取证时点,AFRINIC 新闻页返回 HTTP 200。浏览器标题是“News & Announcements - AFRINIC - Regional Internet Registry for Africa”,页面大标题也是“News & Announcements”。正文继续列出“Latest News & Announcements (2026)”,其中包括 Appeal Committee、CEO designate、成员与利益相关方调查等近期公告。

结构化数据也站在这一边。JSON-LD 的名称写着 News & Announcements,网址字段以 news.html 结束;面包屑和导航同样指向 News。换句话说,新闻路由并没有被隐私政策正文替换,读者也没有遇到 404 或空页。

这份正面证据必须保留。仅因为页面头部有错误字段,就把它描述成“新闻不可用”,会把身份问题夸大成可用性事故。HTTP 200 和新闻正文回答的是“能否到达”;它们还没有回答“页面向机器声明自己是谁”。

第二张身份证:页面头部写的是隐私政策

同一份 HTML 的 canonical 指向 https://afrinic.net/privacy.html。普通 meta description 直接称自己为 AFRINIC 的 Privacy Policy 页面,关键词以 privacy policy 开头。两组 Open Graph 标题都写着“Privacy Policy - AFRINIC - Regional Internet Registry for Africa”,其中绝对网址也指向隐私政策;Twitter 标题和描述沿用同一个身份。

这不是 www 与裸域名之间的普通规范化差异。目标路径已经从 news 变成 privacy.html,内容角色也随之改变。

真正的 AFRINIC 隐私政策页也返回 HTTP 200。它的浏览器标题、H1 和自指 canonical 都一致地说明自己是 Privacy Policy。目标页面本身没有失效;问题恰恰在于新闻页选择了一个有效但不同类的目标。

于是,同一份 HTML 里出现两套都很完整、却彼此冲突的机器身份。只检查字段是否存在,会得到全绿;把字段所指的对象放在一起比较,才会看到失败。

sitemap 没有把两页当成一页

AFRINIC sitemap分别列出 https://www.afrinic.net/news 和 /privacy。它是普通站点 sitemap,不是 Google News Sitemap,也不能证明任何搜索引擎已经收录这两条网址。

它在这里的作用更窄:AFRINIC 自己的公开发现清单把新闻与隐私列为两个资源,而新闻页的 canonical 却试图把前者的首选身份交给后者。这种内部不一致比搜索结果截图更基础,因为它存在于发布源本身。

sitemap 的路径没有 .html,canonical 的目标使用裸域名和 .html。这些网址形态差异也值得在回执里记录,但文章的中心不是尾缀或主机名。决定性差异是“新闻”与“隐私政策”两种内容角色。

canonical 声明关系,不强迫结果

RFC 6596把 canonical 定义为重复内容集合里的首选 IRI。目标必须包含与来源重复的内容,或者是来源内容的超集。这样,应用才可能把处理集中到首选版本。

从捕获到的标题、H1 和正文看,新闻清单不是隐私政策的副本,隐私政策也不是新闻清单的“查看全部”版本。错误标签不会自动创造重复关系。因此,可以准确地说:“新闻页声明隐私政策为 canonical,而两个页面的公开角色不符合该关系。”

不能进一步跳到“搜索引擎已经删除新闻页”。canonical 不是 HTTP 重定向;RFC 也说明,应用遇到不当声明时可以忽略它并采用自己的启发式判断。没有 Search Console、索引状态或流量序列,就没有外部后果的证据。

这条边界很重要。把可能性写成结果,反而会削弱一项本来已经非常清楚的源端事实。

社交身份是另一条证据链

Open Graph 协议把 og:title 定义为对象在图谱中应显示的标题,把 og:url 定义为对象作为永久图谱身份使用的 canonical URL。新闻页提供的这两项值都描述隐私政策。

这证明“源代码向社交读取器提供了错误身份”,但不证明 Facebook、X 或其他服务真的抓取并展示过一张隐私政策卡片。平台可能使用缓存、采用别的字段,或者拒绝冲突值。源输入与平台输出必须分别取证。

JSON-LD 又给出第三种结果:它仍然说这是新闻页。问题因此不是“没有机器可读信息”,而是搜索规范化、社交图谱与结构化数据对同一对象给出不同答案。

发布完成需要一份逐路由回执

每条公开路由都应绑定一份简短的“发布表面身份回执”。它至少记录:请求网址与最终网址、经审定的内容角色、HTML 标题与 H1、canonical 目标以及重复或超集关系的理由、普通描述、Open Graph 与 Twitter 身份、结构化数据的类型/名称/网址、sitemap 条目、实际部署版本或字节哈希、校验结果、例外、修正时间与前后哈希。

校验必须理解含义。只问 canonical 目标是否返回 200,这个案例会通过,因为隐私政策确实返回 200。只问 og:title 是否存在也会通过,因为标题完整存在。真正的问题是:这些字段是否描述了同一个经审定的对象。

对当前两张页面,最小修复不需要删新闻,也不需要改隐私政策正文。它只需让 /news 的 canonical、描述与社交身份重新指向现有新闻内容,并保存修正前后的字节证据。外部缓存何时刷新,应另开一条观察时钟。

不把四个状态压成一个结论

这起事件应保持四个独立状态:路由可达;源身份冲突;外部处理未知;修正尚待新的源页面证明。

四者分开后,判断反而更公平。AFRINIC 的新闻页确实在工作,并公开提供近期公告;机器身份也确实错指另一个页面。承认前者不等于忽视后者,要求修正后者也不需要虚构已经发生的搜索损失。

修正日期不能从 Last-Modified 倒推

新闻响应还带有 Last-Modified: Fri, 28 Aug 2026 17:23:02 GMT。这个值可以帮助绑定本次观察到的文件版本,却不能回答错误从何时开始。它可能对应一次同时修改正文和页面头部的发布,也可能只是服务器对静态文件的更新时间。没有更早字节、提交记录或带日期的抓取,就不能把 8 月 28 日写成故障起点。

同样,未来看到正确 canonical,也只能证明新的观察时点已经修正。要确认完整修正区间,需要保存本次旧哈希、新版本哈希、两次响应时间以及中间是否存在其他发布。身份回执的价值正在这里:它把“现在看起来正确”提升为“哪一份已部署表示在何时替代了哪一份表示”。

这也保护外部平台的证据边界。修正后的源页面与仍然显示旧标题的分享卡片可以同时存在;前者说明源已变,后者可能只说明缓存未刷新。没有两条独立时间线,就会把合理的传播延迟误写成修复失败。

来源