最直接有效的办法是用csp头upgrade-insecure-requests强制浏览器将http子资源升级为https;再配置80端口301跳转确保全站https;对内网http后端需透传x-forwarded-proto;兜底可用sub_filter替换响应体中的硬编码http地址。

最直接有效的办法是让浏览器自动把页面里所有 http:// 请求升级成 https://,不用改前端代码,也不依赖后端是否支持 HTTPS。
用 CSP 响应头强制升级 HTTP 请求
在 Nginx 的 HTTPS server 块(listen 443 ssl)中添加这一行:
add_header Content-Security-Policy "upgrade-insecure-requests" always;
-
upgrade-insecure-requests指令告诉浏览器:当前 HTTPS 页面下所有不安全的 HTTP 子资源请求(图片、脚本、API、样式等),一律升为 HTTPS 发出 -
always确保即使返回 304、500 或其他状态码,这个头也不会丢失 - 只对同源或已配置 CORS 的跨域资源生效;若目标域名本身不支持 HTTPS(如未配证书的 CDN),升级后仍会 404 或证书错误
- 若已有 CSP 头,需合并写法,例如:
"upgrade-insecure-requests; default-src 'self'; img-src https: data:; "
强制 HTTP 全站跳转到 HTTPS
仅加 CSP 不够彻底。用户若通过 http:// 直接访问,初始 HTML 就走 HTTP,后续资源仍可能被生成为 HTTP 链接。
- 新增一个监听 80 端口的 server 块:
server { listen 80; server_name yourdomain.com; return 301 https://$host$request_uri; }- 确保 SSL 模块已启用(
nginx -V | grep http_ssl_module有输出) - 避免 CDN 或代理层缓存了旧的 HTTP 响应,上线后建议清空 CDN 缓存和浏览器本地缓存
代理内网 HTTP 后端时保持协议一致
当后端服务无法启用 HTTPS(如 Spring Boot 内网接口、老旧设备 API),Nginx 可作为 SSL 终结点,对外 HTTPS、对内 HTTP。
- 关键配置示例:
location ^~/api/ { proxy_pass http://192.168.1.10:8080/; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; }-
X-Forwarded-Proto $scheme让后端知道原始请求是 HTTPS,避免重定向循环或生成http://链接 - 前端仍请求
https://yoursite.com/api/login,浏览器全程看到 HTTPS,不触发混合内容拦截
兜底:用 sub_filter 替换响应体中的硬编码 HTTP 地址
适用于 HTML/JS/CSS/JSON 中写死的 http://(如 <img src="http://cdn.com/a.jpg?x-oss-process=image/resize,p_40">),属于内容层补救措施。
- 关闭压缩:在对应 location 中加
proxy_set_header Accept-Encoding "";,必要时加proxy_ignore_headers Content-Encoding; - 显式声明类型:
sub_filter_types text/html application/javascript text/css application/json; - 精准替换(避免误伤):
sub_filter 'src="http://' 'src="https://';、sub_filter "url('http://" "url('https://"; -
sub_filter_once off;确保全文多处匹配都生效 - 该方案不能修复 JS 动态拼接的 URL 或 meta refresh,需配合 CSP 头形成双重保障











