可在负载均衡层用 sub_filter 实时替换 HTTP 为 HTTPS,需关闭压缩、明确 MIME 类型、启用全文替换、确保模块启用且指令同作用域。

可以在负载均衡层用 sub_filter 实时把响应内容里的 HTTP 地址替换成 HTTPS,从而避免混合内容警告和资源加载失败。关键不在“加指令”,而在于让替换真正生效——它对响应格式、压缩状态和 MIME 类型都很敏感。
必须关闭响应压缩
sub_filter 只处理解压后的明文文本。如果后端返回了 gzip 压缩的 HTML 或 JSON,Nginx 不会解压再替换,而是直接透传二进制流,导致替换完全失效。
- 在对应 location 块中显式禁用压缩:gzip off;
- 同时清除客户端可能携带的压缩请求头:proxy_set_header Accept-Encoding "";
- 不推荐依赖
gzip_disable或 UA 判断,它们无法覆盖所有压缩路径
明确指定可处理的 MIME 类型
默认情况下 sub_filter 只作用于 text/html,而现代页面的 JS、CSS、JSON 接口也常含硬编码地址,必须手动声明类型:
- 常用组合:sub_filter_types text/html text/css text/javascript application/javascript application/json;
- 避免使用
*通配,可能误伤text/plain或接口返回的 CSV 等非目标内容 - 确保后端实际返回的
Content-Type与配置一致(可用curl -I验证)
启用全局替换并注意变量用法
硬编码地址往往在页面中多次出现(比如多个 src、href 或 API 调用),默认只替换第一个匹配项:
- 加 sub_filter_once off; 启用全文替换
- 左侧匹配字符串必须是静态值(不支持正则捕获组),但右侧可引用 Nginx 变量:sub_filter 'http://' '$scheme://';
- 若需更灵活匹配(如所有绝对 URL),Nginx 1.9.4+ 支持正则语法:sub_filter /https?:\/\/[^"'\s>]+/ '$scheme://$host';
确保模块已启用且作用域正确
sub_filter 指令必须与 sub_filter_types 和 proxy_pass 在同一配置块(如 location)内,否则静默失效:
- 确认 Nginx 编译时启用了
--with-http_sub_module(运行nginx -V 2>&1 | grep sub_module查看) - 不要把
sub_filter_types写在 http 块而sub_filter写在 location 块——它们必须共存于同一作用域 - 替换不区分大小写,支持中文,但无法处理 base64 编码或二进制内容(如图片、字体)











