最直接有效的办法是用csp响应头upgrade-insecure-requests强制浏览器将http子资源升级为https;补充方案为nginx反向代理伪装http后端为https;兜底方案用sub_filter替换响应体中的http链接。

最直接有效的办法是让浏览器自动把页面里所有 http:// 请求升级成 https://,不用改前端代码,也不依赖后端是否支持 HTTPS。
首选:用 CSP 响应头强制升级协议
在 Nginx 的 HTTPS server 块(listen 443 ssl)中添加:
add_header Content-Security-Policy "upgrade-insecure-requests" always;
-
upgrade-insecure-requests指令告诉浏览器:当前 HTTPS 页面下所有子资源(图片、脚本、API、CSS 等)的http://请求,一律自动改为https://发出 -
always确保即使返回 304、500 或其他非 200 状态码,该响应头也不会丢失 - 该策略只对同源或已配置 CORS 的跨域资源生效;若目标域名本身不支持 HTTPS(如未配证书或服务未监听 443),升级后仍会失败
- 若已有 CSP 头,需合并写法,例如:
"upgrade-insecure-requests; default-src 'self'; img-src https: data:; "
补充:反向代理“伪装”HTTP 后端为 HTTPS
当后端服务确实无法启用 HTTPS(如内网 Spring Boot、老旧设备接口),可让 Nginx 对外提供 HTTPS,对内仍走 HTTP:
示例配置:
location ^~/api/ {<br> proxy_pass http://192.168.1.10:8080/;<br> proxy_set_header Host $host;<br> proxy_set_header X-Forwarded-Proto $scheme;<br> proxy_set_header X-Real-IP $remote_addr;<br>}
- 前端请求
https://yoursite.com/api/login,Nginx 转发到http://192.168.1.10:8080/login - 关键在于
X-Forwarded-Proto $scheme,让后端知道原始请求是 HTTPS,避免生成http://重定向或跳转链接 - 此方式浏览器全程看到 HTTPS,不会触发混合内容拦截
兜底:用 sub_filter 替换响应体中的 HTTP 链接
适用于 HTML/JS/CSS/JSON 中硬编码的 http:// 地址(如 <img src="http://cdn.com/a.jpg?x-oss-process=image/resize,p_40">):
关键配置项:
- 关闭压缩:
gzip off;和proxy_set_header Accept-Encoding "";(否则sub_filter失效) - 显式声明类型:
sub_filter_types text/html application/javascript text/css application/json; - 精准替换:
sub_filter 'src="http://' 'src="https://';、sub_filter "href='http://" "href='https://"; - 启用全局替换:
sub_filter_once off;
配套必须检查项
- 确保 80 端口有 301 强制跳转:
return 301 https://$host$request_uri;,从源头杜绝 HTTP 访问 - 验证响应头是否生效:用浏览器开发者工具 → Network → 查看任意 HTML 响应的 Response Headers,确认含
Content-Security-Policy: upgrade-insecure-requests - 清除浏览器缓存再测试,避免旧响应被缓存导致误判
- 若资源来自第三方 CDN,确认其域名已部署有效 HTTPS 证书,否则升级后仍 404 或证书错误











