页面只渲染了一半,一张样式表在网络面板中灰显,而 VPN 客户端仍报告隧道健康。这三种观察同时成立,因为浏览器评判的是页面发出的请求,隧道在那次评判中没有发言权。了结此事靠的是决定而非设置:修复引用、升级给主机所有者,或者放弃这项依赖。每个选项都有便宜的验证方法,选错就会浪费一轮支持。

为什么隧道覆盖不了子资源

混合内容始于一个通过明文 HTTP 请求子资源的 HTTPS 文档。每个 URL 按自己的协议方案受评判,父文档的保护永远不会延伸到子请求。加在浏览器之下的加密改变的是线上传输的内容,而不是标记里要求的 http://。

现代浏览器把这些请求分成两类并区别对待。脚本、样式表、iframe 以及通过 fetch、XMLHttpRequest 或 WebSocket 发出的调用会被直接拒绝,不会先尝试升级。图片、音频和视频会被改写成 https:// 并重新请求,一旦这次安全获取失败,加载就被放弃。主机是裸 IP 地址的子资源 URL 免于升级,所以 IP 主机上的 HTTP 图片会继续被拦截,而不是被悄悄修好。这种区分(包括可升级一侧的那项豁免)记录在Mozilla 的混合内容指南中。Chrome 对从安全页面发起的非安全下载也采用类似拒绝,这就是 PDF 链接可能在周围页面看起来完好时失效的原因。

因此那条灰显记录是控制生效的证据,而不是隧道泄露明文的证据。把它当成指向单个引用的发现,而不是整页的问题。

判断这条不安全引用归谁

在动手之前,先按产生位置给问题 URL 分类。这个答案决定你能否今天就发布修复、是否需要供应商发版,或者这项依赖必须离开页面。到网络面板的 Initiator 列去读,因为屏幕上的标记常常是运行时拼装的。

URL 来自哪里谁能修它第一步
硬编码在你部署的模板或片段里你换成 https:// 形式,然后清除缓存
由标签管理器或供应商捆绑包注入供应商,附上你的工单发出确切的 URL、请求类型和控制台行
仅在 80 端口提供,没有 TLS 监听主机所有者申请 TLS、在前面放一层你自己控制的东西,或者放弃它

当主机已经在 443 上应答、只有引用写着 http 时,修复是本地的:改引用、清页面缓存,确认该行变成 https。只监听 80 端口的主机没法靠编辑达标,所以资源要么搬家,要么前面加一层你控制的东西,要么被去掉。标签管理器注入的 URL 即使你自己的模板是干净的也会继续出现,这种情况应当提交工单,附上确切 URL 和控制台行。让员工放行非安全内容不属于这些选项,因为它会让该浏览器配置访问的每个站点都失去这项检查。

修引用,而不是改浏览器设置

在保留网络日志的情况下重载失败流程,并按可疑主机筛选面板。控制台会点名 URL 和指令,这能在你碰模板之前判定请求是被拒绝还是被升级。

curl -sSI https://cdn.example.org/vendor.js | head -n 1
curl -sS -o /dev/null -w '%{http_code} %{url_effective}\n' -L https://cdn.example.org/vendor.js

另有两项辅助控制值得了解,但都不能替代修复。带有upgrade-insecure-requests的 Content-Security-Policy 响应头会让浏览器在离开页面前改写 http 子资源 URL,这能抓到尚未找到的旧引用。改写后的请求在目标主机不提供 HTTPS 时仍然失败,所以响应头只改变浏览器尝试哪个 URL。HSTS 按主机生效,这意味着你自己域名上的策略对从未发送该头的第三方 CDN 毫无作用。改完模板后清页面缓存,并在渲染后的 HTML 中搜索旧主机名,因为同一个 URL 也可能来自片段、翻译字符串或数据库字段。

也要跟踪重定向,因为以 https:// 开头的链条可能落到 http:// 地址,而浏览器评判的是最后一跳。上面第二条命令的-L形式会替你打印出那个最终 URL。如果最后一跳是纯 http,引用仍然是错的,即使你改过的链接看起来没问题。

用控制台和网络面板确认页面

清空缓存后重载,并把流程再走一遍,包括按需加载内容的按钮。首次加载会隐藏懒加载组件、地图瓦片和点击后才出现的播放器脚本。控制台里不应再有混合内容条目,你碰过的每一行都应显示 https。在关闭工单前截取控制台和请求行,因为下一次部署之后这种状态很难重建。

当资源属于别人时,发四样东西:确切的 URL、请求类型、控制台文本以及它出现的页面。粘贴进工单的任何内容都要隐去会话标识。只说图片坏了的报告,等于让所有者无从搜索。

修复落在产生请求的那条引用上时,隧道照做自己的事。部署之后再在模板和供应商捆绑包里搜一次主机名,只有当控制台不再剩下被拦截的混合内容条目时才关掉这个案子。

相关文章