灰度阶段只让少量真实用户或少量入口走 HTTPS,样本小、路径集中,很多例外不会出现;全量发布后,入口来源、旧链接、内嵌资源和第三方脚本同时放大,HTTP 与 HTTPS 的差异才从“传输层加密”变成“同一份内容存在两套可访问地址”。这才是小流量通过、全量却暴露问题的根本原因。
HTTP 与 HTTPS 在协议层的区别是明文与 TLS 加密,但对发布决策更关键的是:它们通常被视为两个不同的源(origin)。灰度如果只覆盖新页面、站内跳转和现代浏览器,那么同源策略、Cookie 作用域、绝对地址引用这些差异都不会被触发。全量后,用户从旧 HTTP 链接进入、从收藏夹进入、从外部站点跳入,才第一次让两套源同时活跃。
判断灰度结论能不能外推,先看三个条件是否同时成立:
http:// 绝对地址,包括图片、脚本、样式和接口;只要有一项在灰度中没被抽到,全量出现例外就不奇怪,也不代表灰度结论错了,只代表它的适用范围比想象中窄。
保留 HTTP 可访问并跳转。适用于外链存量多、短期无法全部更新的站点。前提是跳转目标稳定、跳转链不形成循环,并且跳转本身不掩盖页面内的混合内容。动作上,先抓取一批旧 HTTP 地址,记录跳转后的最终地址,再看最终页面里是否仍加载 HTTP 资源。若跳转正常但页面内仍有 HTTP 资源,浏览器地址栏显示的是 HTTPS,内容却可能被拦截或降级,这属于全量后才暴露的典型例外。
改写为相对地址或协议相对地址。适用于模板统一、资源集中在少数组件里的站点。前提是能定位所有硬编码位置,而不是只改首页模板。改写后需要重新走一遍灰度,确认同一页面在两种入口下渲染一致,再进入全量。
退出本次全量、回到灰度。适用于例外集中在登录、支付或第三方回调等强依赖源的环节。前提是先能复现例外,而不是因为“看到报错就回退”。回退后应保留复现步骤和触发入口,否则下一次全量仍会重复同一问题。
全量后出现异常,不要直接归因于 HTTPS 本身。可以按下面这组证据区分:
https:// 改成 http:// 后行为是否不同。若不同,问题在源与跳转;若相同,问题更可能在发布内容本身。这四步的作用是先把“协议差异”与“发布差异”分开,再决定是继续全量、局部改写还是回退。
假设某站点灰度只对 5% 的新访客启用 HTTPS,页面模板统一、资源用相对地址,登录 Cookie 未设 Secure。灰度期间登录正常,因为用户从同一入口进入,Cookie 在 HTTPS 下写入也在 HTTPS 下读取。全量后,一部分用户从旧 HTTP 书签进入,服务端跳转到 HTTPS,但 Cookie 因未设 Secure 仍可能被旧 HTTP 上下文覆盖,于是出现“跳转成功却掉登录”的例外。
此时正确动作不是回退全部 HTTPS,而是先给 Cookie 加上 Secure 并限定 Domain,再重新灰度验证跳转路径。若验证通过,下一步再全量;若不通过,才考虑对登录相关路径暂时退出全量。这个例子中的数字仅用于说明样本覆盖与例外暴露的关系,不代表任何真实站点表现。
HTTPS 不保证安全无漏洞,也不保证排名;它只是把传输加密并改变源的标识。不同搜索引擎对协议切换、跳转和索引的处理需分别核查,不能拿一个引擎的表现推断另一个。灰度能证明的,只是“被抽到的那部分路径在当前条件下成立”。全量发布前,把入口、资源引用和 Cookie 三个边界逐项对照,才是避免例外被放大的实际做法。