sub_filter动态升级http为https需确保响应未压缩、覆盖多类型资源、精准匹配属性值并配合其他安全机制。需禁用压缩、扩展sub_filter_types、限定替换上下文、修正重定向及添加csp头等。

在多级代理场景下,用 sub_filter 动态把页面里的 HTTP 静态链接升级为 HTTPS,核心不是“能不能换”,而是“换得准、换得稳、不被跳过”。它必须穿透压缩、绕过缓存干扰、覆盖多种响应类型,并避开 DOM 解析盲区。
确保明文响应流可被读取
sub_filter 只处理未压缩的纯文本。只要上游返回 Content-Encoding: gzip 或 br,替换就完全失效。
- 在 proxy location 块中加
proxy_set_header Accept-Encoding "";,主动告诉后端“别压缩” - 避免依赖
gunzip on;—— 它不支持 Brotli,且增加 CPU 开销 - 禁用 Nginx 自身压缩:
gzip off;(location 级即可,无需全局)
扩展 sub_filter_types 覆盖常见资源类型
默认只处理 text/html,但现代页面常把 JS/CSS/JSON 配置内联在 HTML 中,这些内容里的 http:// 同样会触发混合内容警告。
- 至少配置:
sub_filter_types text/html application/javascript text/css application/json; - 若含 SVG 内嵌 HTML 或 XHTML 页面,追加
application/xhtml+xml - 不要写
sub_filter_types *;—— 它会扫描所有响应体,包括二进制文件,徒增开销
限定上下文精准替换,避免误伤
直接替换 http:// 极易出错:可能改掉注释里的示例地址、JS 字符串中的协议名、甚至 https:// 里的子串。
- 优先匹配属性值开头:
sub_filter 'src="http://' 'src="https://'; - 覆盖主流引用方式,逐条添加:
sub_filter 'href="http://' 'href="https://';、sub_filter "url(http://" "url(https://";、sub_filter 'https://'; - 如需兼容性更强,可用相对协议:
sub_filter 'src="http://' 'src="//';(前提是全站已启用 HTTPS)
配合其他机制堵住漏网之鱼
sub_filter 只修响应体,而混合内容还可能来自重定向头、Referer 控制或浏览器策略。
- 修正跳转:
proxy_redirect http:// https://;,防止 302 返回 HTTP 地址 - 兜底升级:
add_header Content-Security-Policy "upgrade-insecure-requests"; - 清理敏感头:
proxy_hide_header Referer;或proxy_set_header Referer "";,避免第三方图床因 HTTP Referer 拒绝加载 - 禁用 ETag:
proxy_ignore_headers ETag;,防止替换后的 HTML 被缓存为“固定版本”











