sub_filter可在Nginx代理层安全修正HTTPS页面中硬编码的HTTP静态资源地址,需关闭后端压缩、显式声明响应类型、启用全量替换,并按HTML属性边界精准匹配引号内链接,配合proxy_redirect、Host头及CSP头形成完整修复链。

用 sub_filter 在 Nginx 代理层修正 HTTPS 页面里硬编码的静态资源地址,核心是让 Nginx 在返回 HTML、CSS、JS 前,把其中的 HTTP 或旧域名链接替换成当前安全的 HTTPS 地址。它不是万能补丁,但对后端无法修改、又急需上线 HTTPS 的场景非常实用。
必须先确保响应可被替换
sub_filter 只处理明文文本,所以这三步缺一不可:
- 关闭后端压缩:在 location 中加
proxy_set_header Accept-Encoding "";,或启用gunzip on;(需编译时含 gunzip 模块) - 显式声明支持类型:默认只处理
text/html,要修 JS/CSS 中的链接,得写sub_filter_types text/html text/css application/javascript; - 允许全部替换:
sub_filter_once off;,否则只改第一个匹配项
精准匹配比全局替换更安全
直接替换 http:// 容易误伤(比如 JSON 字段、注释、JS 字符串里的协议字面量)。推荐按 HTML 属性边界来写规则:
sub_filter 'src="http://old.com/' 'src="https://new.com/';sub_filter "src='http://old.com/" "src='https://new.com/";sub_filter 'href="http://old.com/css/' 'href="https://new.com/css/';
注意引号类型要跟源码一致;如果页面混用单双引号,两条都配上更稳妥。
配合其他指令形成完整修复链
sub_filter 只动响应体,头信息和跳转逻辑还得靠别的指令兜底:
- 用
proxy_redirect http://old.com/ https://new.com/;修正Location和Refresh响应头中的跳转地址 - 用
proxy_set_header Host new.com;让后端生成的绝对 URL 基于新域名 - 加响应头
add_header Content-Security-Policy "upgrade-insecure-requests";,作为浏览器端自动升级请求的后备方案
常见陷阱与绕过思路
有些情况 sub_filter 确实无能为力,得提前识别:
- 内联 JS 中动态拼接的 URL(如
document.write('<script src="'%20+%20protocol%20+%20'//cdn.com/a.js')%EF%BC%89%E2%86%92%20%E6%97%A0%E6%B3%95%E5%8C%B9%E9%85%8D%EF%BC%8C%E9%9D%A0%20CSP%20%E5%A4%B4%E5%85%9C%E5%BA%95 %0A%20%20 - CSS%20%E9%87%8C%E7%9A%84%20
url(http://...)%20%E2%86%92%20%E9%9C%80%E7%A1%AE%E4%BF%9D%20text/css%20%E5%9C%A8%20sub_filter_types%20%E4%B8%AD%EF%BC%8C%E4%B8%94%E6%8B%AC%E5%8F%B7%E4%B8%8D%E9%9C%80%E8%BD%AC%E4%B9%89%EF%BC%88sub_filter%20%E6%98%AF%E7%BA%AF%E5%AD%97%E9%9D%A2%E5%8C%B9%E9%85%8D%EF%BC%89 %0A%20%20 - %E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84%E5%86%99%E6%88%90%E6%A0%B9%E8%B7%AF%E5%BE%84%EF%BC%88%E5%A6%82%20
/static/js/app.js%20%E5%8D%B4%E8%AF%A5%E6%98%AF%20/app/static/js/app.js%EF%BC%89%E2%86%92%20%E5%8F%AF%E7%94%A8%20sub_filter%20'/static/'%20'/app/static/';%20%E8%A1%A5%E6%95%91 %0A

















