浏览器
Mixed Content 混合内容警告:找出 HTTPS 页面里的 HTTP 资源
Mixed Content: The page at 'https://example.com/' was loaded over HTTPS, but requested an insecure resource混合内容警告的意思是:HTTPS 页面里有一部分文件是通过明文 HTTP 加载的。 页面本身加密了,那些 HTTP 资源没有,所以浏览器会拦截脚本和框架,对图片则尝试升级或拦截。结果是地址栏不再显示安全,严重时页面排版错乱、按钮点不动。
先判断是网站的问题还是你电脑的问题
混合内容几乎都是网站自己的代码造成的,访客修不了,也不该由访客修。少数情况下是浏览器扩展、或者某些网络在页面里注入了 HTTP 内容(比如运营商广告注入),用无痕窗口或换个网络就能排除。
先用 SSL 检测 确认证书本身没问题:
curl ssl.sh/example.com
然后用 混合内容扫描 扫页面,或者按 F12 打开开发者工具,在“控制台”里找以 “Mixed Content” 开头的行。
原因
混合内容有 4 种来源,最常见的是模板或文章里写死了 http:// 地址。
1. 模板或文章里写死了 http:// 地址
老文章、主题文件、编辑器经常保存绝对地址 http://。找出来:
curl -s https://example.com/ | grep -oE 'src="http://[^"]+"|href="http://[^"]+\.css"' | sort -u
2. CMS 的站点地址还是 HTTP
WordPress 之类的系统按保存的站点地址生成链接,那里写的还是 http://,生成的每个链接都不安全。
wp option update home 'https://example.com'
wp option update siteurl 'https://example.com'
wp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid
没有 WP-CLI 的话,可以在宝塔面板的数据库管理里先备份,再用插件做批量替换。
3. 第三方资源不支持 HTTPS
老的统计代码、图床、外链 CDN 没有 HTTPS。图片放在阿里云 OSS、腾讯云 COS 或七牛等对象存储上的,要给自定义域名配置 HTTPS 证书,再把地址改成 https://;实在不支持的资源,换掉或者下载到自己服务器上。
4. 后端在代理后面,以为自己是 HTTP
TLS 在 CDN 或负载均衡上终止,源站收到的是 HTTP,程序就生成 http:// 链接。CDN 回源时传 X-Forwarded-Proto,并让程序信任它。
在各浏览器/系统上的样子
| 浏览器 | 显示内容 |
|---|---|
| Chrome / Edge / 360 / QQ 浏览器 | 控制台:“Mixed Content: The page at ... was loaded over HTTPS, but requested an insecure ...”;网站信息里提示连接并非完全安全 |
| Firefox | 控制台:“已阻止载入混合活动内容”之类的提示;锁图标带警告 |
| Safari | 网页检查器控制台显示被拦截的不安全内容 |
站长怎么修
根本修法是把所有资源地址改成 https:// 或相对路径,upgrade-insecure-requests 只作兜底。
1. 所有资源地址改成 https:// 或相对路径。代码和数据库都要搜,不能只看首页。
2. 清理期间加一个兜底响应头:
add_header Content-Security-Policy "upgrade-insecure-requests" always;
宝塔面板在“网站 → 设置 → 配置文件”里加到 server 块中即可。
3. 告诉程序它在 HTTPS 后面。
proxy_set_header X-Forwarded-Proto $scheme;
4. HTTP 跳转 HTTPS,全部资源都正常加载后,再考虑开启 HSTS,让浏览器以后不再用 HTTP 访问你的网站。
5. 重新扫描。 用 混合内容扫描 复查,并看一遍关键页面的控制台。
常见问题
混合内容对访客有危险吗?
有。HTTPS 页面里的 HTTP 脚本或框架可以被网络路径上的任何人篡改,进而控制整个页面,所以浏览器会拦截。图片风险低一些,但仍会暴露你在看什么。
能在浏览器设置里允许不安全内容吗?
Chrome 可以按网站允许,但这只改了你自己的浏览器,而且会削弱这个网站的保护。作为访客建议保持拦截;作为站长,把地址改好,谁都不用改设置。
加了 upgrade-insecure-requests 就够了吗?
不一定。它会在请求发出前把 http:// 子资源改写成 https://,前提是那个资源本身支持 HTTPS。不支持 HTTPS 的外部资源照样加载失败,还是要替换或修好。