nginx sub_filter可代理层自动将http://替换为https://以解决混合内容警告,需同时禁用压缩、显式声明mime类型、关闭单次替换,并注意模块启用、location覆盖、状态码限制及生效验证。

用 Nginx 的 sub_filter 在代理层把页面里硬写的 http:// 链接自动改成 https://,是解决混合内容警告最直接的方式。它不改后端代码,也不动前端资源,只在响应发出前做一次轻量文本替换。
核心配置三要素
要让替换真正生效,必须同时满足以下三点:
-
禁用响应压缩:后端若返回 gzip 内容,
sub_filter就读不到明文。加这行:proxy_set_header Accept-Encoding ""; -
显式声明 MIME 类型:默认只处理
text/html,但 CSS、JS、JSON 里的链接也常出问题。建议写:sub_filter_types text/html text/css application/javascript application/json; -
开启全文替换:默认只换第一个匹配项。加
sub_filter_once off;才能修复所有http://
典型 HTTPS 修正写法
常见硬编码形式包括协议头、完整 URL、相对路径拼接等,对应替换策略如下:
- 统一协议升级:
sub_filter 'http://' 'https://';(注意末尾斜杠,避免误替http://example.com中的http) - 修复跳转地址(如 meta refresh 或 JS location):
sub_filter "http://$host" "https://$host";(用变量更安全,避免影响其他域名) - 补全协议缺失的资源:
sub_filter 'src="/js/' 'src="https://$host/js/';(需配合引号和路径边界,防止误替)
容易忽略的关键细节
很多配置看似正确却失效,往往卡在这几个环节:
-
模块是否启用:运行
nginx -V 2>&1 | grep -o with-http_sub_module,无输出说明未编译该模块 -
location 范围是否覆盖:
sub_filter只在当前location块内有效。若静态资源走独立路径(如/static/),需单独配或用通配location / { ... } -
响应状态码限制:默认只处理 200、201、204、206、301、302、303、304、307、401、403、404、405、410、411、413、414、415、494、495、496、497、499、500、501、502、503、504、505 等状态码。若后端返回非标准码(如 299),需用
sub_filter_last_modified on;或调整逻辑
验证是否生效的方法
别只看页面是否显示正常,要确认替换真的发生了:
- 用
curl -s https://yourdomain.com/page.html | grep http://检查原始响应里是否还有http:// - 浏览器打开开发者工具 → Network → 点开 HTML 请求 → 查看 Response 标签页,搜索关键词
- 临时加一行
sub_filter 'body>' 'body><!-- sub_filter active -->';,刷新后源码中出现注释即表示模块工作正常











