通过Nginx的sub_filter在负载均衡层将响应体中http://替换为https://,并配合add_header Content-Security-Policy "upgrade-insecure-requests;"实现双重防护,可高效解决Mixed Content问题。

直接在负载均衡层用 sub_filter 修复混合内容,核心是让 Nginx 在把后端响应发给浏览器前,把其中所有明文 http:// 替换成 https://,同时确保替换能真正生效——这比改源码或前端更轻量,适合无法控制后端输出的场景。
必须关闭响应压缩
sub_filter 只处理未压缩的明文响应。如果后端返回 gzip 压缩内容,Nginx 默认不会解压再替换,导致指令“静默失效”。
- 在 location 块中显式禁用压缩:
proxy_set_header Accept-Encoding ""; - 避免 upstream 主动返回
Content-Encoding: gzip;必要时可加proxy_ignore_headers Content-Encoding; - 不建议用
gzip off;全局关压缩,应只对需要 sub_filter 的路径生效
精准匹配并覆盖所有 MIME 类型
默认 sub_filter 只处理 text/html,但混合内容常藏在 JSON 接口、内联 JS、CSS 或 meta 刷新跳转里。
- 强制处理常见文本类型:
sub_filter_types text/html text/css application/javascript application/json text/plain; - 若不确定类型,可用
sub_filter_types *;(注意:Nginx 1.19+ 支持,旧版本需列全) - 特别注意:JSON 响应必须包含
application/json,否则替换完全不触发
替换逻辑要完整且安全
只替换 http:// 容易漏掉协议相对 URL 或硬编码域名,还可能误伤非 URL 内容(如注释、字符串字面量)。
- 基础修复:
sub_filter 'http://' 'https://';+sub_filter_once off; - 增强兼容性:补充替换常见绝对路径前缀,例如:
sub_filter 'src="http://' 'src="https://';、sub_filter "url('http://" "url('https://"; - 避免跨域污染:若后端返回的是第三方域名(如
http://cdn.example.com),应只替换你可控的域名,而不是全局http://
配合 CSP 头做双重保险
sub_filter 是内容层兜底,CSP 是浏览器层强制升级,两者叠加更可靠。
- 添加响应头:
add_header Content-Security-Policy "upgrade-insecure-requests;"; - 该头会指示浏览器自动将页面中所有 HTTP 资源请求升级为 HTTPS,即使 HTML 里没改过来
- 注意:它不能修复跳转(如
meta http-equiv="refresh")或 JS 动态拼接的 URL,这部分仍依赖 sub_filter











