本次实测结果

22 / 22

公开文章 URL 返回 HTTP 200,没有请求失败。

22 / 22

canonical 与 Article 主页面 URL 指向自身。

22 / 22

Article 与 BreadcrumbList 可解析,日期字段存在。

22 / 22

去除已确认的边缘改写后,与 main 文件一致。

一、为什么要比较“仓库里的 HTML”和“公网真正返回的 HTML”

静态网站通常给人一种直觉:GitHub 里是什么文件,用户和爬虫拿到的就是什么文件。实际链路并没有这么短。代码先进入分支和提交,再由部署系统生成站点,域名请求经过 CDN、边缘安全与统计功能,最终才形成浏览器或爬虫收到的响应。任何一层都可能出现旧版本、部署遗漏、缓存滞后或响应改写。

对普通读者而言,只要页面能够正常打开,少量边缘差异可能没有可见影响;对 GEO 与技术审计而言,最终响应才是公开信源。搜索爬虫、AI 搜索爬虫和其他抓取工具通常不会读取私有 GitHub 仓库,它们看到的是域名返回的 HTML、HTTP 头和可访问资源。如果团队只检查仓库,就可能漏掉边缘层添加、删除或替换的内容。

这次测试与此前的robots、sitemap 与结构化数据公开审计不同。此前重点是不同入口是否互相冲突;本次重点是逐篇文章做“部署后同一性”核验:内容是否已经从 main 到达公网,结构化数据是否仍指向正确 URL,以及 Cloudflare 对最终 HTML 做了什么变化。

可引用要点:静态站点的事实版本不能只用仓库文件判断。对外公开的真实版本,是域名在特定时间、请求条件和边缘节点下实际返回的 HTTP 响应。

二、测试对象、时间和基线怎样确定

测试时间为 2026 年 8 月 21 日。仓库基线是测试开始时 main 分支的最新提交 4202889df65a9d5c2ad58ca9a103d6d01581fa9a,对应前一日发布的“AI 品牌信息纠错”文章。我们完整读取该提交下的 sitemap,从中筛选路径符合 /blog/basics/英文-slug/、/blog/methodology/英文-slug/ 和 /blog/tests/英文-slug/ 的独立文章页面,得到 22 个 URL,没有按结果抽样。

每个公开 URL 都使用普通桌面浏览器 User-Agent 发起 GET 请求,并增加只用于本次核验的查询参数,降低本地复用旧响应的可能。请求带有 Cache-Control: no-cache,但这并不等于强制所有中间层刷新,也不代表其他用户会经过同一个 Cloudflare 节点。我们保存状态码、响应头和响应正文,再把公开 URL 与仓库路径一一映射。

本次请求观察到响应服务器为 Cloudflare,样本响应的 CF-Ray 后缀为 ORD;22 个响应的 CF-Cache-Status 都是 DYNAMIC,且 Cache-Control 为 public, max-age=0, must-revalidate。这些是本次条件下的观察,不应外推为所有地区、所有时间或无查询参数请求的固定缓存策略。

仓库内容通过 GitHub 文件对象读取。GitHub 官方文档把 blob 定义为保存文件内容的 Git 对象,而 commit 是文件层级与内容的快照。我们用确定的提交 SHA 固定基线,避免审计过程中 main 新增文章后,前后两批文件来自不同版本。

三、具体检查了哪些项目

第一层是可访问性。每个 URL 必须返回 200,并返回可解码的 HTML;这只能说明请求成功,不等于内容正确。第二层是页面身份:canonical 是否等于当前文章的目录式公开 URL,Article JSON-LD 的 mainEntityOfPage.@id 是否同样指向该 URL。若两者指向旧 slug、测试域名或另一篇文章,页面即使能打开,也会向机器提供冲突身份。

第三层是结构化数据基本完整性。我们解析页面中所有 application/ld+json 脚本,确认 Article 与 BreadcrumbList 均能作为 JSON 读取,并检查 Article 同时包含发布日期和修改日期。这里没有因为“脚本存在”就判定通过;不能解析、类型错误或主页面 URL 不一致,都应视为失败。

第四层才是正文版本对照。我们先直接比较公开 HTML 与仓库 HTML,再定位差异。直接比较结果为 22 篇全部不同,但不能因此得出部署漂移结论,因为 Cloudflare 会在响应经过边缘时执行已启用的改写。只有识别并标准化确定的边缘变换,剩余差异才可能代表正文、元数据或模板未部署。

第五层是日期和索引关系。文章页面的日期必须与其 JSON-LD 一致,新文章还要出现在 sitemap、内容中心、分类页、llms.txt 和 feed 中。本次文章发布前的 22 篇均已在 sitemap 中形成唯一 URL;本篇发布后会再对新增后的索引执行同样检查。

检查项通过标准实测结果不能代表什么
公开访问HTTP 200,正文可读取22 / 22不代表搜索系统已经索引或引用
canonical与当前公开 URL 完全一致22 / 22不代表平台一定采用该规范 URL
Article 主页面mainEntityOfPage 指向自身22 / 22不代表结构化数据会被任何模型采用
JSON-LD 与日期Article、BreadcrumbList 可解析,日期存在22 / 22不代表日期内容一定真实,仍需与可见正文核对
原始 HTML直接逐字符相同0 / 22失败不等于正文漂移,需先识别边缘改写
标准化 HTML仅剔除确认的 Cloudflare 改写后相同22 / 22不覆盖浏览器渲染、资源加载和地区差异

四、为什么原始 HTML 是 0 篇一致,却不是部署失败

22 篇公开响应都出现两类仓库中不存在的变化。第一类是邮箱地址保护:页脚原本的 mailto:hello@geoc.ai 被改写为 /cdn-cgi/l/email-protection 形式,邮箱文字被替换为编码标记,同时页面末尾加入用于恢复显示的 email-decode.min.js。第二类是 Cloudflare Web Analytics 的 beacon.min.js 模块脚本,它同样在最终响应中出现,而不在 GitHub 文章源文件中。

Cloudflare 官方文档说明,Email Address Obfuscation 会在 HTML 中隐藏邮箱,减少机器人采集,同时尽量保持真实访客可见和可点击;官方更新还说明解码脚本由边缘注入。Web Analytics 文档则说明,站点启用相应功能后,RUM beacon 可以在 HTML 响应经过边缘网络时自动加入,用于采集页面加载时间等性能指标。

这意味着“仓库不存在外部脚本”与“公网响应不存在外部脚本”是两个不同命题。GEOC 仓库文章没有主动引用 Cloudflare Analytics,但代理层当前会把该脚本注入最终 HTML。对代码审查而言,应检查仓库;对用户性能、内容安全策略和爬虫可见性而言,应检查最终响应。两者不能互相替代。

我们的标准化没有删除任意不一致段落。处理规则只有三项:忽略文件开头的 BOM 与换行差异;把页脚邮箱区域替换成同一占位符;移除明确匹配 Cloudflare 邮箱解码和 Web Analytics 地址的脚本。随后重新逐字符比较,22 篇全部与固定提交中的对应文件一致。标题、正文、元数据、JSON-LD、导航和内链没有被标准化规则跳过。

五、边缘改写对 AI 可读性意味着什么

最直接的结论不是“Cloudflare 好”或“Cloudflare 坏”,而是爬虫读取的最终信源可能与源站文件不同。邮箱保护的目标就是让自动抓取工具不容易直接取得邮箱,因此品牌如果希望某个联系字段被机器可靠理解,不应只依赖被保护的页脚邮箱。可以在合适的公开联系页用清楚语境说明联系渠道,并确保结构化数据与可见内容遵守隐私和业务要求;但也不应为了机器读取而关闭必要的反采集保护。

统计脚本则属于页面运行依赖。它通常不改变 Article 正文和结构化数据,却会改变响应字节、资源请求和内容安全策略。使用“线上文件哈希必须等于 Git blob 哈希”作为部署监控时,如果不先处理边缘注入,系统会持续误报。更稳妥的监控应分别保留源文件完整性、边缘变换清单和最终页面语义检查。

对于生成式搜索,canonical、Article 和正文一致比原始字节完全相同更重要,但这仍不是引用保证。爬虫可能不执行邮箱解码脚本,也可能忽略统计脚本;不同系统如何处理 JavaScript与边缘改写没有统一公开规则。站点应把核心品牌事实保留在不依赖脚本的正文中,把受保护的联系方式视为一种交互入口,而不是唯一实体证据。

如果要进一步理解页面、robots、sitemap 与 CDN 最终响应之间的关系,可以结合此前的 AI 可读性审计。那次发现源站与边缘 robots 的表现不完全相同,本次则证明文章正文在剔除已知边缘变换后保持一致。两次结果共同说明:边缘层值得单独审计,但不能把所有差异都叫作错误。

可引用要点:仓库 HTML 与公网 HTML 不同,既可能是部署漂移,也可能是 CDN 的预期改写。可靠审计必须先固定提交,再识别允许的边缘变换,最后比较没有被允许规则覆盖的正文和元数据差异。

六、CF-Cache-Status 为 DYNAMIC 应该怎样理解

Cloudflare 官方文档把 CF-Cache-Status 作为判断资源缓存状态的响应头。本次 22 个带核验参数的文章请求全部返回 DYNAMIC,说明这些具体响应没有以普通边缘缓存命中的形式交付。它不证明 Cloudflare 完全没有参与请求,也不证明不带参数的文章永远不会缓存。

测试请求主动加入不同查询参数,并要求不复用缓存,这些条件本身可能影响缓存键与规则。Cloudflare 官方缓存规则文档还指出,某些绕过设置会返回 DYNAMIC,而不是统一显示另一个“绕过”标签。因此本文只报告“本次 22 次请求观察到 DYNAMIC”,不把它写成网站长期配置事实。

从部署一致性角度,DYNAMIC 并没有造成旧正文:22 个标准化响应都与当前 main 基线匹配。但这只能覆盖本次节点和时间。真正的缓存回归测试还应比较无参数 URL、多次重复请求、不同地区节点、HIT/MISS/REVALIDATED 变化和部署前后时间线;缺少这些条件,就不能对全网缓存传播速度作定量结论。

七、怎样设计一个不会大量误报的版本一致性监控

第一步固定基线,不要直接读取不断变化的 main。每次发布后记录最终提交 SHA,并从该提交读取应公开的文件。第二步维护 URL 映射:目录式 URL 应对应明确的 public/.../index.html,重定向和归档页单独处理,避免把合法跳转当作缺失。

第三步把比较分成三层。传输层检查状态码、内容类型、服务器与缓存头;身份层检查 canonical、Article 主页面、标题、日期和结构化数据;内容层比较正文。只有内容层需要标准化,而且允许规则必须足够窄、可解释、带来源。像“删除所有 script”“压缩全部空白”“只比较文字”这样的宽规则会掩盖真实部署错误。

第四步保存差异样本。若比较失败,应输出第一个差异位置、前后上下文、响应头、URL、提交 SHA 和时间,而不是只给一个红色状态。团队需要判断差异来自新部署、旧缓存、边缘功能、A/B 实验还是源站异常。没有上下文的哈希失败无法指导修复。

第五步加入语义检查。即使 HTML 与仓库完全一致,仓库本身仍可能写错 canonical、日期或内链。版本一致性只回答“是否部署了预期文件”,不回答“预期文件是否正确”。因此它应该与可见正文和 Article JSON-LD 一致性检查、XML 验证及站内链接审计组合使用。

  1. 01 / BASELINE固定提交

    记录 SHA 与应发布文件清单。

  2. 02 / RESPONSE抓取公开响应

    保存状态、响应头和原始 HTML。

  3. 03 / NORMALIZE只处理允许变换

    边缘规则逐项命名,不泛化删除。

  4. 04 / VERIFY再做语义校验

    检查身份、日期、结构化数据和正文。

八、发现不一致时,怎样从第一处差异定位责任层

如果标准化后仍然不一致,先不要把公网内容覆盖回仓库,也不要重新发布整个网站。应先找到第一处差异以及差异所属区域。若差异出现在标题、描述、canonical 或 JSON-LD,优先检查构建模板、文章元数据与部署版本;若差异只出现在页脚或安全脚本附近,检查边缘配置;若正文整段仍是上一版本,检查部署任务是否选错提交、输出目录是否正确以及旧构建产物是否被重新使用。

还要比较响应头与时间。如果状态是 HIT,Age 较大且正文为旧版,可能需要检查缓存清理和缓存键;如果是 DYNAMIC 仍返回旧文,问题更可能位于源站构建或部署别名;如果不同请求落到不同节点并返回两个版本,应保存各自 CF-Ray、时间和完整响应,不能只保留一次“正常”的结果。状态头只是线索,不是自动归因。

若只有一个 URL 异常,要检查这个 URL 是否曾经改名、是否存在重定向、是否被单独设置规则,以及 sitemap、站内链接和 canonical 是否仍指向旧路径。若所有文章以相同方式异常,则更像公共模板、边缘设置或整个部署版本问题。范围判断可以显著减少无效排查:单页问题从内容责任开始,全站问题从共享链路开始。

正文差异还要区分“内容变化”和“编码表示变化”。BOM、换行符、HTML 实体、属性顺序与空白压缩可能不改变页面语义,但任意删除它们也会掩盖问题。审计工具应同时保存原始响应和标准化结果,并让每条标准化规则有名称、示例和批准原因。发现未知差异时先失败、再人工解释,不能让程序自动把未知内容加入忽略列表。

九、怎样把这项检查接进每天的文章发布流程

每天发布新文章时,可以把检查拆成发布前和发布后两部分。发布前在固定树对象上验证新文章、旧文回链、内容中心、分类页、sitemap、llms.txt 和 feed,确保这组文件内部一致;发布后再从公开域名读取同一组 URL,确认最终响应已经出现新 slug、标题、日期和结构化数据。两阶段回答不同问题:前者防止错误提交,后者防止正确提交没有到达公网。

发布后不需要立刻抓取所有历史页面,但应至少检查新文章、被修改的旧文章、两个列表页和三个机器入口。全站 22 篇一致性审计可以按固定周期运行,或在公共模板、CDN、统计和邮箱保护配置变化后运行。这样既能控制请求量,也能在共享规则变化时及时发现全站影响。

自动化报告应保留三类结果。第一类是硬失败,例如非 200、JSON 无法解析、canonical 指向错误域名或标准化后正文不同;第二类是观察项,例如缓存状态改变、边缘节点变化或新增已知脚本;第三类是平台不可验证项,例如搜索是否已经收录、AI 是否采用页面。只有第一类应阻止发布,观察项需要趋势记录,不可验证项不能包装成成功。

当自动化准备直接更新 main 时,还要在写入前重新读取分支头。如果基线提交已经变化,就应停止并重新合并,而不是强制移动引用。发布后再回读最终提交中的全部修改文件,确认 blob 与预期内容一致。这样才能把“生成内容”“提交内容”“公网内容”串成三段可追溯证据,而不是只留下一个成功提示。

百度普通收录、IndexNow 或其他 URL 通知也应放在部署确认之后。通知接口接收 URL,只代表发现流程被触发;如果公网仍是旧页面,越快推送只会越快暴露旧版本。正确顺序应是先验证公开 HTML,再通知索引渠道,最后单独记录接口响应和后续收录状态。

十、五种常见错误与反例

第一,只看页面是否打开。200 页面可能仍是旧内容、软错误页或错误 canonical。第二,只比较原始哈希。启用邮箱保护、统计注入、HTML 压缩或安全标记后,合法边缘变化会让哈希永久不同。第三,为了让比较通过而删除所有脚本和空白,这会把真正的脚本篡改、JSON-LD 丢失和正文格式错误一并隐藏。

第四,用当前 main 对比几分钟前抓到的公开页面。若发布恰好发生在两次读取之间,基线本身就不一致。应该固定提交,再检查分支是否发生变化。第五,把一次节点的 DYNAMIC、HIT 或 MISS 当成整个网站的缓存策略。缓存状态与 URL、查询参数、请求头、规则、节点和时间相关,单次结果只能描述当次响应。

还有一个内容层面的反例:看到公开响应增加外部脚本,就立即断言网站违反“零境外依赖”。仓库约束与最终边缘响应确实需要分别检查,但结论应说明脚本是谁、在哪里加入、作用是什么、是否可配置以及对核心内容有什么影响。本次能确认 Cloudflare 官方文档描述了自动注入机制;不能仅凭 HTML 推断是哪位管理员何时开启了配置。

十一、可执行复测清单

发布后版本一致性检查

  • 记录最终 main 提交 SHA、树对象和发布文件清单,避免使用移动基线。
  • 从 sitemap 读取全部独立文章,不按已知正常页面抽样。
  • 逐页保存状态码、content-type、cache-control、CF-Cache-Status 与边缘节点标识。
  • 确认 canonical 和 Article mainEntityOfPage 都等于当前公开 URL。
  • 解析 Article 与 BreadcrumbList,而不是只搜索脚本标签。
  • 检查发布日期、修改日期与页面可见信息是否存在并相互一致。
  • 先保存原始 HTML,再应用命名明确、范围最小的边缘标准化规则。
  • 邮箱保护、统计注入、压缩和安全改写应分别记录,不能合成“忽略差异”。
  • 标准化后仍有差异时,输出差异上下文,不直接覆盖仓库或公网版本。
  • 公开页面全部通过后,再同步检查内容中心、分类页、llms.txt、robots、sitemap 与 feed。

十二、团队报告应该怎样写,才不会把技术通过误解成 GEO 效果

版本一致性报告的标题和结论必须限定对象。本次能够说的是“指定提交下的 22 篇文章,在指定时间和请求条件下,公开响应的核心 HTML 与仓库一致”;不能缩写成“网站没有任何问题”,更不能写成“AI 已经收录全部文章”。前者是部署证据,后两者分别需要资源加载、浏览器体验、搜索索引和模型回答等不同测试。

报告中应同时保留通过项与观察项。通过项包括状态码、页面身份、结构化数据解析和标准化内容;观察项包括 Cloudflare 邮箱改写、统计脚本、DYNAMIC 状态、ORD 节点与请求参数。观察项不一定要立即修复,但必须让后来的人知道公网为什么不等于 Git blob,避免下次审计再次把预期差异当成事故。

如果结果用于发布决策,应明确阻断阈值:新文章非 200、canonical 或 Article URL 错误、正文版本不符、XML 无效、旧文回链缺失,都应停止完成报告;统计脚本版本更新、边缘节点变化等未知差异则先转为人工复核。阻断规则太宽会让正常发布频繁失败,太松又会把真正的版本漂移带到公网。

最后,报告要保存原始证据而不仅是汇总数字。至少包括 URL 清单、提交 SHA、请求时间、User-Agent、状态头、标准化规则版本和失败差异上下文。这样未来出现缓存争议或内容变更时,团队能够复现当时结论,而不是依靠一句“当时检查过了”。

十三、测试边界与局限

本次是一次部署一致性快照,不是长期性能测试。请求集中发生在 2026 年 8 月 21 日,使用一个执行环境、普通桌面 User-Agent 和带核验参数的 URL;样本响应由 Cloudflare ORD 节点处理。我们没有覆盖其他国家和地区节点、真实搜索爬虫 User-Agent、登录状态、IPv6 差异、重复缓存命中或一天内的持续变化。

测试比较的是 HTML 响应,没有运行完整浏览器渲染,也没有逐项下载 CSS、JavaScript、图片、二维码或字体资源。因此“22 篇标准化 HTML 一致”不能证明每个视觉资源都加载成功,也不能证明移动端没有布局溢出。此前尝试启动本地浏览器渲染环境时缺少可用内核,所以本文没有把静态 CSS 推断写成移动端实测结果。

标准化规则只针对本次实际观察到并能由官方文档解释的 Cloudflare 邮箱保护与 Web Analytics 注入。若未来边缘功能改变脚本地址、增加 HTML 压缩、进行 A/B 测试或插入其他安全标记,当前规则可能失效;正确动作是复查新差异,而不是继续扩大忽略范围。

最后,部署一致不等于内容正确,也不等于任何模型会抓取、索引、引用或推荐这些页面。它只证明在给定条件下,公开站点交付了与指定提交相同的核心文章版本,并保持了基本页面身份和结构化数据。

十四、资料依据与复现说明

本文数据来自 GEOC 私有仓库指定提交和 geoc.ai 公开响应,观察日期为 2026 年 8 月 21 日。以下官方资料仅用于解释 Git 对象、邮箱保护、Web Analytics 注入和缓存响应头;所有 22 篇通过数量均来自本次实际检查,不是平台宣传数据。

可引用要点:本次对当前 main 的 22 篇 GEOC 文章逐页检查,公开 URL 全部返回 200;canonical、Article 主页面 URL 和日期字段全部通过;去除已确认的 Cloudflare 邮箱保护及统计注入后,22 份公开 HTML 与仓库文件全部一致。

下一步阅读

部署一致性确认了“预期版本是否到达公网”,下一步仍需判断页面之间是否形成可理解的信息路径。下一步可以继续检查文章之间的引用网络,判断断链、孤岛、单向关系和入口集中度怎样独立于部署状态存在。

← 返回内容中心