mixed content 报错从哪来:27 个首页 10,138 条资源地址零 http://,8 个站还开着那条能兜底的 CSP

mixed content 是 HTTPS 页面把某一部分走明文 HTTP 拉进来。2026-09-12 这 27 个首页的 HTML 写了 10,138 条子资源地址,没有一条以 http:// 开头。剩下的:4 个站 24 条不带协议的 // 地址、3 个站 6 条 http:// 超链接、8 个站还发着 upgrade-insecure-requests 当保险,其中 2 个连规范已宣布作废的 block-all-mixed-content 也一起发。

抓取与收录10 分钟读完856 次阅读
mixed content 报错从哪来:27 个首页 10,138 条资源地址零 http://,8 个站还开着那条能兜底的 CSP

实测 · 2026-09-12 · 30 个域名 · 27 个可读 · 单次抓取

样本 / 口径:仍是 2026-08-15 起在用的那 30 个站,2026-09-12 各请求一次首页,桌面 Chrome UA、HTTP/2、跟随跳转、不执行 JavaScript。留下最终响应的全部头和 HTML 原文,把 HTML 里每一个会让浏览器去取东西的地址都数了一遍。canva.com、medium.com、stackoverflow.com 对我们返回 403,纳入统计的是 27 个。

mixed content 指一个 HTTPS 页面把自己的某一部分走明文 HTTP 拉进来。2026-09-12 这 27 个首页的 HTML 一共写了 10,138 条子资源地址,没有一条以 http:// 开头。旧协议剩下的痕迹很具体:4 个站上 24 条不带协议的 // 地址,3 个站上 6 条 http:// 超链接,以及 8 个站还在 Content-Security-Policy 里发着的一条保险 upgrade-insecure-requests。8 个里有 2 个还同时发着规范已经宣布作废的那条。

先说那行报错是什么意思

搜这个词的人多半是在控制台里撞见了一行以 Mixed Content: The page at 开头的提示,后面跟着你的页面地址和一个 http:// 的资源地址。它的结尾只有两种。一种是浏览器替你把这条请求改成了 https:// 再去取,取不到就不显示;另一种是直接拦下,连试都不试。走哪一种不看你,看资源类型:图片、音频、视频是前一种,脚本、样式表、iframe、fetch 请求,以及写在 srcset 里的任何图片,是后一种。两种的修法是同一处改动:把 http:// 改成 https://,或者把协议整个去掉让它跟着页面走。下面的数字,说的是 27 个大站今天还剩多少这种地址。

怎么测的

一次请求、从外部、不登录任何账号。从 HTML 里取所有会触发抓取的属性:scriptimgiframesourcevideoaudioembedsrcimgsourcesrcsetobjectdata;以及 rel 是抓取类(stylesheetpreloadmodulepreloadprefetch、图标、manifest)的 linkhref。每条地址按协议归类。另外单独读了每一条 a href、每一个 canonicalalternateog:imageog:urltwitter:image,JSON-LD 里的 urlimagelogosameAs,以及响应头或 meta 标签里的 Content-Security-Policy

# 这一页在任何脚本跑起来之前,会让浏览器去取的所有 http:// 地址
curl -sL --compressed -A 'Mozilla/5.0 (Macintosh) Chrome/126.0' https://example.com/ \
  | grep -oiE '(src|srcset|href|data)="http://[^"]+"' | sort | uniq -c

# 页面有没有让浏览器替它升级
curl -sI -A 'Mozilla/5.0 (Macintosh) Chrome/126.0' https://example.com/ \
  | grep -i '^content-security-policy' | grep -oiE 'upgrade-insecure-requests|block-all-mixed-content'

四条局限。我们没有执行 JavaScript,脚本之后注入的资源不在这里,而 reddit.com 这种 HTML 只有 8 KB 壳的页面,几乎所有东西都是之后注入的。我们没有解析 CSS,样式表里的 background-image: url(http://…) 这一次看不见。首页只是一个网址,最可能还留着老 http:// 图片的是十年前的一篇博客,不是门面。数的是地址字符串,不是网络请求:浏览器看见 img 里的 http:// 会先改写成 https:// 再去取,这正是本篇讲的那个行为。

27 个首页 10,138 条子资源地址:mixed content 是零

这个词真正指的那个数,在这块面板上是零。10,138 条里,1,507 条属于不安全时会被浏览器直接拦下的那类(脚本、样式表、preload、框架),8,631 条属于浏览器会先试着升级的那类(图片、媒体、图标)。两类里一条 http:// 都没有。492 条元数据地址(canonical、alternate、Open Graph、Twitter card)和 JSON-LD 里的 398 条地址值同样干净。

首页抓取地址http:////http 链接升级指令HSTS
techcrunch.com1,900010有,两条
www.theverge.com1,841000
www.wired.com861003
substack.com814001
www.bbc.com754002
www.framer.com563000
about.gitlab.com334000
stripe.com328000
www.notion.com327000
arstechnica.com326000有,两条
www.figma.com214000
webflow.com213010
www.shopify.com203000
supabase.com201000
slack.com192000
www.nytimes.com174000
nextjs.org163000
github.com1570210
www.mozilla.org145000
react.dev103000
vercel.com101000
www.cloudflare.com80000
railway.com80000
www.netlify.com45010
www.wikipedia.org12000
news.ycombinator.com6000
www.reddit.com1000

「升级指令」指 CSP 里的 upgrade-insecure-requests,「两条」指同时带着 block-all-mixed-content。HSTS 那一列和 2026-08-30 发的 strict-transport-security 实测 一样,仍是 27 个里 25 个,没发的仍是 wired.com 和 railway.com。

剩下的 http:// 是 6 个站上的 30 个字符串

残余分两种,两种都不是 mixed content。24 条抓取地址写成了不带协议的 //主机/路径,这种写法跟着页面的协议走。其中 21 条在 github.com 上,全是同一个资源主机上的图片;另外 3 条各是一段第三方脚本,分别在 netlify.com、techcrunch.com、webflow.com。在 HTTPS 页面上它们解析成 https://,浏览器从头到尾没见过不安全请求。这种写法是页面可能两种协议都要伺候的那些年留下的化石。

站点类型条数指向什么
github.com// 图片21images.ctfassets.net 上的标志与产品图
www.netlify.com// 脚本1js.hs-scripts.com(HubSpot)
techcrunch.com// 脚本1ak.sail-horizon.com(Sailthru)
webflow.com// 脚本1go.webflow.com/js/forms2(Marketo 表单)
www.wired.comhttp:// 链接3Condé Nast 隐私政策 ×2、aboutads.info
www.bbc.comhttp:// 链接2自己站上的邮件订阅页
substack.comhttp:// 链接1某位作者的子域名

那 6 条 http:// 超链接是第二种。链接是导航,不是子资源,Mixed Content 规范写明了这一点:指向顶层浏览上下文的导航请求 "are not considered mixed content"(W3C Mixed Content,2023 年 2 月 23 日候选推荐草案,2026-09-12 读取)。4 个不同的落点我们 2026-09-12 都跟了一遍,每个都是一跳到达 https:// 页面。奇怪的是 bbc.com,它从一个发着 HSTS 的页面上,用明文 HTTP 链接自己的域名,两次;浏览器会在这一下点击离开之前把它升级掉。Wikipedia 另有 369 条不带协议的超链接,每个语言版本一条,列在这里只为完整,不算数。

8 个站还在发 upgrade-insecure-requests,2 个还带着已作废的那条

这条指令让浏览器在发出页面自己的不安全请求之前先改写它。用它的规范的话说,它存在是为了 "to reduce the burden of migrating websites from insecure origins by reducing the negative side effects of mixed content blocking"(W3C Upgrade Insecure Requests,2022 年 10 月 13 日编辑草案,2026-09-12 读取)。27 个首页里 19 个有 Content-Security-Policy,18 个发在响应头里,gitlab.com 写在 meta 标签里;19 个里 8 个带这条指令:arstechnica.com、cloudflare.com、figma.com、github.com、mozilla.org、nytimes.com、stripe.com、techcrunch.com。这 8 个站在面板上一条可升级的 http:// 子资源都没有,所以这条指令是给将来某次误改上的保险,不是在修现在的毛病。纽约时报把它放在 13 条指令的第 1 条;Cloudflare 把它放在 14 条的最后一条,一条 1,959 字符的头的末尾。

首页头长度指令数升级排第几block-all
www.nytimes.com576131
www.mozilla.org1,4281310
arstechnica.com3631111有(第 10)
www.figma.com2,3931212
techcrunch.com4911512有(第 13)
github.com3,8201514
www.cloudflare.com1,9591414
stripe.com1,7911816

8 个里有 2 个,arstechnica.com 和 techcrunch.com,还同时发着 block-all-mixed-content。Mixed Content 规范专门给它开了一节,标题就叫 "Obsolescences":"An earlier version of this specification defined the block-all-mixed-content CSP directive. It is now obsolete, because all mixed content is now blocked if it can't be autoupgraded." 同一段把另一条留了下来:"upgrade-insecure-requests … is not obsolete because it allows developers to upgrade blockable content." 两条一起发没有害处。它也是一枚日期戳,标着这条策略上一次被人从头读过是什么时候。

面板上有一条策略反着来。gitlab.com 的 meta CSP 在 default-srcscript-srcstyle-srcimg-src 里都把 http: 列为允许的来源。这不会造出 mixed content,浏览器的混合内容规则在策略允许什么之上照跑。它只说明:哪天真有人往页面里加了一段 http:// 脚本,这条策略不会是拦住它的那一道。

为什么这个数是浏览器压出来的,不是站点自觉的

Chrome 不再把一张不安全的图片当警告看,而是直接改写。2019-10-03 公布的计划是,Chrome 80 起 "mixed audio and video resources will be autoupgraded to https://, and Chrome will block them by default if they fail to load over https://",图片随后跟上(Chromium Blog,No More Mixed Messages About HTTPS,2026-09-12 读取)。图片那一步推迟了,文章自己的更新写着 "delayed until at least Chrome 84",Chrome Platform Status 里 "Autoupgrade Image Mixed Content" 这一条记的是第 86 个版本起默认启用(2026-09-12 读取)。脚本、样式表、框架在这之前就已经是直接拦下的。

规范现在描述的就是这么演变出来的网络。内容要么是 "upgradeable",图片、视频、音频请求,浏览器改写成 https://,改写后取不到就丢弃;要么是 "blockable",其余的一切。有一个例外值得抄下来:可升级那一类 "does not include img elements that use srcset or picture",因为 imageset 这个目标在升级机制出现之前就被定义成 blockable,而 "the decision was to not upgrade any content that was previously defined as blockable"(W3C Mixed Content,同一文档)。写在 srcset 里的 http:// 候选是被拦,不是被升级。这块面板上 8,631 条可升级类型的地址里,6,907 条来自 srcset 属性,所以这条例外是这一类的大头,不是脚注。

地址栏那把锁是对整条链的承诺,不是对锁头的。链上有一环是 http://,浏览器要么换掉它,要么剪断它。

Google Search 的文档里根本没有这个词

我们找过搜索侧的规则,没找到。Search Console 的 HTTPS 报告列了六种「HTTPS 网址不是被收录的那个」的原因:"HTTP marked with canonical tag"、"HTTPS has invalid certificate"、"Sitemap points to HTTP"、"HTTPS has redirect"、"HTTPS URL is roboted"、"HTTPS not evaluated",mixed content 不在其中(HTTPS report,2026-09-12 读取)。页面体验指南对这个主题只问了一句 "Are your pages served in a secure fashion?",到此为止。JavaScript SEO 基础那页说 Google Search "runs JavaScript with an evergreen version of Chromium"(Last updated 2026-03-04),也就是上面描述的那个浏览器;但 Google 的渲染器对一条 http:// 样式表是不是同样先升级再拦下,我们没找到写下来的说法,也没有测。要是一条被拦的样式表或脚本改变了渲染器看到的东西,该去看的是 URL Inspection 里的渲染后 HTML,不是这篇实测。

这对你意味着什么

独立站的门面多半是干净的,残余在老主题、老文章和 CSS 里,还有 CDN 迁移之前写死的图片地址。拿上面第一条命令对你最老的五个网址各跑一遍,再决定要不要加那个头。

  • 站点只要有任何一部分曾经走过 HTTP,就在边缘加一次 Content-Security-Policy: upgrade-insecure-requests。成本是一个头,换来的是将来某张 http:// 图片变成一条 https:// 请求,而不是一张破图。
  • srcset 里的 http:// 要手动改。浏览器不升级它们,只拦。
  • 确认你升级过去的每个主机在 443 上真的应答。规范说得明白,升级失败 "no fallback"。
  • 别往新策略里加 block-all-mixed-content。规范已经叫它作废,浏览器早就在做它要求的事。
  • 别指望这条指令修好指向别人站的 http:// 超链接。同一份规范写着 "Links to third-party sites will not be upgraded",链接不是子资源。

如果你升级的那条资源正是 AI 爬虫需要的,比如一张不藏东西的样式表、一段把正文渲染出来的脚本,改完用 AI 爬虫可达性检查 看一眼爬虫还够不够得着它。同一条 CSP 里 unsafe-inline 那一半是另一篇实测:扫描器标红的 unsafe-inline

常见问题

你们是怎么测的?

2026-09-12 对每个首页发一次 curl 请求,HTTP/2、桌面 Chrome UA、跟随跳转、压缩传输,头和正文都落盘。然后用一个 Python HTML 解析器读出每一个会触发抓取的属性和每一条链接,按协议归类,再从响应头或 meta 标签里读 CSP。上面每个数字都是脚本从落盘文件重算出来的,没有一个是手打的。第二遍单独跟了 4 个 http:// 链接的落点。

mixed content 报错怎么解决?

找到那行提示里引用的 http:// 地址,在你的 HTML 或 CSS 里改成 https://,或者去掉协议写成 //主机/路径。改完以后再在边缘加 upgrade-insecure-requests,防下一次。要是那个主机根本不提供 HTTPS,换主机,升级失败没有退路。

"mixed content 已屏蔽" 是什么意思?

浏览器把那条请求拦下了,连试都没试。被拦的是脚本、样式表、iframe、fetch,以及写在 srcset 里的图片。普通 img、视频、音频不会显示「已屏蔽」,它们会被先改写成 https://,改写后取不到才不显示。

mixed content 影响 SEO 吗?

2026-09-12 我们找到的 Google Search 文档里,没有一份这么说。HTTPS 报告查的是被收录的网址是不是 HTTPS,不是页面加载了什么。唯一说得通的路径是:一条被拦的样式表或脚本让 Google 的渲染器看到的东西变了;这个我们没有测。要是你的站有一段被拦的脚本负责把页面拼出来,那先是一个渲染问题,不是一个 mixed content 问题。

只加 upgrade-insecure-requests 够不够?

对你自己页面的子资源,够,前提是每个被升级的主机都在 HTTPS 上应答,有一个不应答就没有退路。它不碰指向别人站的链接,也不会修一条写着 http:// 的 canonical 或 sitemap,那是 Search Console 的事,不是浏览器的事。

为什么 27 个大站会一起归零?

没问过它们,这是本次实测的局限,不是结论。数据能说的只有终态:任何一条抓取地址里都没有 http://,27 个里 25 个发 HSTS,8 个站在已经没有东西可升级的时候还开着升级指令。

mixed content 报错从哪来:27 个首页 10,138 条资源地址零 http://,8 个站还开着那条能兜底的 CSP