网站已经安装 SSL 证书,通过 https:// 访问也能正常打开,但浏览器地址栏仍显示页面存在安全问题。
这种情况不一定意味着证书安装失败。
如果主页面通过 HTTPS 加载,但页面内部仍请求 HTTP 图片、CSS、JavaScript、字体或接口,就可能产生 Mixed Content,也就是“混合内容”。
在企业网站从 HTTP 切换到 HTTPS、旧站改版或者服务器迁移时,这类问题比较常见。真正排查时,不能只检查证书,还要顺着页面实际发出的网络请求逐项确认。
下面以 Nginx + HTTPS 网站 + 浏览器开发者工具 作为示例环境,具体服务器版本、目录结构和应用框架以实际项目为准。
一、先确认问题是不是 Mixed Content
打开网站后,可以先按 F12 进入浏览器开发者工具,再查看 Console。
如果页面存在混合内容,通常可以看到包含:
Mixed Content
的提示。
浏览器一般还会指出:
当前 HTTPS 页面加载了哪个 HTTP 地址;
这个地址属于图片、脚本还是接口;
该请求是否被浏览器阻止。
例如页面本身是:
但其中某张图片仍然使用:
http://example.test/uploads/a.jpg
这时就可以确定问题并不在当前页面协议,而在内部资源地址。
二、先从 Network 面板定位具体 HTTP 请求
只看页面源代码并不一定能找到全部问题。
有些资源来自 CSS,有些由 JavaScript 动态请求,还有一些可能由后台内容生成。
可以在 Network 面板中重新加载页面,并查看实际请求地址。
重点检查:
图片;
CSS;
JavaScript;
字体;
接口请求;
第三方资源。
如果发现仍以 http:// 开头的请求,先记录资源类型和来源,再判断应该从哪里修改。
这种方式比直接在程序里全局搜索更容易确定问题范围。
三、检查后台历史内容里的图片地址
企业网站启用 HTTPS 之前,后台文章或产品详情中可能保存过完整图片地址。
例如旧内容里写的是:
http://example.test/uploads/product-a.jpg
即使网站模板已经切换成 HTTPS,这些历史正文内容也不会自动改变。
因此,排查时需要检查:
旧文章;
产品详情;
专题页面;
富文本内容;
以前上传的附件地址。
如果这些资源属于当前网站,并且已经可以通过 HTTPS 正常访问,可以根据实际情况调整地址。
对于同站资源,在系统结构允许的情况下,也可以使用相对路径,例如:
/uploads/product-a.jpg
这样页面使用 HTTP 还是 HTTPS 时,就不需要在正文里固定协议。
四、检查 CSS 中隐藏的 HTTP 图片
有些图片不是写在 HTML 中,而是通过 CSS 加载。
例如:
.banner {
background-image: url("http://example.test/images/banner.jpg");
}
页面源码里可能看不到这个 HTTP 地址,但浏览器加载 CSS 后仍然会请求它。
修改时可以调整为:
.banner {
background-image: url("/images/banner.jpg");
}
或者在确认资源支持 HTTPS 的情况下使用 HTTPS 地址。
所以排查 Mixed Content 时,除了正文,还需要检查样式文件中的:
background-image
@font-face
url()
等资源引用。
五、检查 JavaScript 和接口基础地址
接口地址也是混合内容比较容易出现的位置。
例如前端代码中写死:
fetch("http://api.example.test/data");
当页面通过 HTTPS 加载时,这个接口请求仍然是 HTTP。
更适合长期维护的方式,是把接口基础地址放在项目配置中,根据不同环境统一管理,而不是分散写在多个 JavaScript 文件里。
例如可以把接口地址作为环境配置:
API_BASE_URL=https://api.example.test
然后由应用统一读取。
这样以后修改域名、协议或者部署环境时,不需要逐个文件寻找地址。
六、第三方资源不要直接批量替换协议
如果 HTTP 地址属于当前网站自己控制的资源,通常比较容易处理。
但如果来自第三方,例如:
第三方字体;
统计脚本;
地图接口;
外部图片;
公共 JavaScript 文件;
外部 API;
就不能直接把所有 http:// 批量改成 https://。
因为第三方服务器未必支持 HTTPS。
正确的检查顺序应该是:
确认资源来源;
确认对方是否提供 HTTPS 地址;
检查替换后的资源能否正常访问;
确认是否具有合法使用权限;
无法安全加载的资源再考虑替换来源。
这样可以避免解决 Mixed Content 后,又出现资源加载失败的问题。
七、HTTP 访问入口要统一跳转到 HTTPS
网站已经使用 HTTPS 后,还需要确认旧的 HTTP 入口是否统一跳转。
Nginx 可以根据实际域名配置类似规则:
server {
listen 80;
server_name example.test;
return 301 https://$host$request_uri;
}
这样用户访问:
时,会跳转到:
需要注意:
这个配置只能解决“用户从 HTTP 地址进入网站”的问题。
如果 HTTPS 页面里面仍然引用:
那么页面内部 Mixed Content 仍然需要单独处理。
八、反向代理环境要检查协议识别
有些网站的 HTTPS 在 Nginx、负载均衡或者其他代理层终止。
代理再把请求转给后端程序时,内部可能使用 HTTP。
如果后端程序不知道外部访问实际上是 HTTPS,就可能自动生成 HTTP 地址。
这种情况下,可以检查代理是否传递外部协议,例如:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
同时还要确认后端框架是否正确识别可信代理传递过来的协议。
不同程序框架处理方式并不完全相同,因此这一部分需要结合实际技术栈检查。
如果页面里的 HTTP 地址是程序自动生成的,而不是人工写入的,这个位置尤其值得检查。
九、数据库中的旧地址不要直接全部替换
网站运行时间较长以后,数据库中可能已经存有很多完整 HTTP 地址。
发现这种情况后,不建议直接执行:
“把数据库所有 http:// 全部替换成 https://”。
因为数据库中可能同时存在:
本站资源;
第三方资源;
外部文章引用;
旧接口;
不支持 HTTPS 的地址。
比较稳妥的做法是先统计。
例如先找出包含本站旧域名的内容,再判断哪些字段可以修改。
修改之前应做好数据库备份,并先在测试环境验证。
尤其是富文本字段,批量替换时还需要注意不要破坏已有 HTML 内容和数据结构。
十、检查静态文件中是否还有旧协议
除了数据库,还可以检查部署目录中的前端文件。
例如在 Linux 环境下,可以根据项目目录使用类似方式查找:
grep -R "http://" /path/to/site/
这一步可以帮助发现:
CSS 中的旧图片地址;
JavaScript 中的接口;
配置文件;
静态 HTML;
遗留模板。
需要注意,这只是查找工具。
搜出来的每一个地址都需要确认用途,不能看到 http:// 就直接替换。
十一、Content-Security-Policy 可以辅助,但不能代替整改
有些网站会配置:
Content-Security-Policy: upgrade-insecure-requests
它可以让浏览器尝试把部分 HTTP 请求升级成 HTTPS。
这种配置在迁移过程中可以发挥辅助作用,但不适合拿来掩盖页面内部长期存在的错误地址。
如果目标服务器根本不支持 HTTPS,自动升级以后一样会请求失败。
所以更稳定的处理方法仍然是:
定位 HTTP 请求;
确认资源来源;
修改真实资源地址;
重新检查页面;
再根据网站实际需求决定是否增加安全策略。
十二、修复以后怎样验证
修改完成后,不要只看浏览器地址栏的锁图标。
可以重新打开开发者工具进行一次完整验证。
建议检查:
Console 是否还有 Mixed Content 提示;
Network 中是否还存在 HTTP 资源;
CSS 和 JavaScript 是否正常加载;
图片和字体是否显示正常;
接口请求是否全部使用 HTTPS;
HTTP 入口是否跳转到 HTTPS;
旧文章和产品详情是否还有历史资源;
移动端页面是否也正常。
如果网站栏目较多,还应该抽查不同类型页面。
首页没有问题,并不代表几年前的旧文章也已经完成迁移。
十三、为什么 HTTPS 迁移要作为完整流程处理
企业网站启用 HTTPS,看起来只是增加了一张证书,实际却会影响整个资源加载链路。
需要检查的通常包括:
服务器证书;
HTTP 跳转;
HTML;
CSS;
JavaScript;
图片;
字体;
接口;
第三方资源;
数据库历史内容;
反向代理协议。
任何一个环节继续产生 HTTP 地址,都可能让浏览器出现混合内容提示。
因此,在网站建设或旧站 HTTPS 改造过程中,把 Mixed Content 检查加入上线验证流程,会比上线以后根据用户反馈逐页修复更容易管理。
结果验证
修复完成后,应确认页面通过 HTTPS 正常访问,浏览器 Console 不再出现 Mixed Content 警告,Network 中页面主要资源和接口均使用 HTTPS,请求状态正常,HTTP 入口可以按预期跳转到 HTTPS。
经验总结
网站安装 SSL 证书只是 HTTPS 部署的一部分。遇到“证书正常但页面仍不安全”时,更有效的排查方式是从浏览器实际请求开始,逐项检查页面资源、历史内容、接口和代理配置,而不是反复重新安装证书。
本文由梓彤超越(武汉)科技有限公司整理。