要让 Nginx 的 sub_filter 仅作用于 JS 文件,必须显式配置 sub_filter_types 为 application/javascript 和/或 text/javascript,并确保响应头 Content-Type 精确匹配;若后端未正确设置 MIME 类型,需通过 types 指令或 proxy_set_header 修正,同时禁用 gzip 和启用 proxy_buffering off 以保障替换生效。

要让 Nginx 的 sub_filter 仅作用于 JS 文件(即 text/javascript 或 application/javascript),关键在于正确配置 sub_filter_types,并确保响应 MIME 类型准确匹配。
明确 sub_filter_types 的作用机制
sub_filter_types 用于扩展 sub_filter 的生效范围,默认只处理 text/html。它不是“白名单过滤器”,而是“匹配后才启用替换”的前提条件:Nginx 先检查响应头中的 Content-Type 是否落在 sub_filter_types 列表中,满足才执行 sub_filter 替换逻辑。
因此,若只想处理 JS 文件,应显式列出 JS 对应的 MIME 类型:
-
text/javascript(传统常用) -
application/javascript(RFC 4329 推荐) - 可选:
text/ecmascript(极少用,按需添加)
确保响应真实携带目标 MIME 类型
即使配置了 sub_filter_types application/javascript;,如果后端返回的 JS 文件实际是 text/plain 或未设置 Content-Type,替换也不会触发。常见原因包括:
- 静态 JS 文件由 Nginx 直接 serve,但
types模块未将.js映射到正确 MIME 类型 - 后端应用(如 Node.js、Python)手动设置了错误或缺失的
Content-Type
验证方式:用 curl -I https://example.com/script.js 查看响应头中的 Content-Type。若不匹配,需修正 MIME 映射:
types {
application/javascript js;
}完整配置示例(仅对 JS 文件做路径替换)
以下配置实现:访问 /static/app.js 时,将其中所有 /api/v1/ 替换为 https://backend.example.com/api/v1/,且仅对 JS 响应生效:
location ~ \.js$ {
# 确保 JS 文件有正确 MIME 类型
types { application/javascript js; }
<pre class='brush:php;toolbar:false;'># 启用 sub_filter 并限定类型
sub_filter_types application/javascript text/javascript;
sub_filter '/api/v1/' 'https://backend.example.com/api/v1/';
sub_filter_once off; # 替换全部匹配项,非仅首个
# 必须关闭缓冲(否则 sub_filter 可能失效)
sub_filter_last_modified on;
proxy_buffering off;
# 若是代理 JS,需透传 Content-Type
proxy_pass https://origin_backend;
proxy_set_header Accept-Encoding "";}
注意事项与排错提示
-
sub_filter是流式处理,不支持正则、不支持跨行匹配,仅适合简单字符串替换 - 若 JS 被 gzip 压缩,需禁用压缩(
proxy_set_header Accept-Encoding "")或启用gunzip on(需编译时含 gunzip 模块) - 使用
sub_filter_last_modified on可避免因缓存导致替换不生效 - 调试时开启
error_log /path/to/error.log debug;,查看是否出现sub filter: no match或 MIME 不匹配日志


















