Nginx sub_filter 可在响应返回前动态替换 HTML 中的环境变量占位符,实现运行时配置注入;需启用模块、禁用 gzip、配置精确字符串替换并验证原始 Response 内容。

Vue 项目打包后是静态文件,无法在运行时读取服务器环境变量。Nginx 的 sub_filter 模块可以在响应返回给浏览器前,对 HTML 内容做字符串替换,从而实现“动态注入”环境配置,无需构建多套包。
前提条件:确保 sub_filter 模块已启用
Nginx 默认可能未编译 sub_filter 模块(尤其在 Alpine 或精简版中)。可通过以下方式确认:
- 执行
nginx -V 2>&1 | grep -o with-http_sub_module,有输出说明已支持 - 若无输出,需重新编译 Nginx 并添加
--with-http_sub_module - 注意:
sub_filter不支持正则,仅做字面量精确匹配替换
在 index.html 中预留可替换占位符
修改 Vue 项目 public/index.html,在 或 底部插入一段带唯一标识的 JS 脚本,例如:
其中 %%API_BASE%% 和 %%APP_VERSION%% 是自定义占位符,确保足够独特,避免误替换。
立即学习“前端免费学习笔记(深入)”;
在 Nginx 配置中启用 sub_filter 替换
在对应 server 或 location 块中添加如下配置(注意顺序和作用域):
sub_filter '%%API_BASE%%' 'https://api.prod.example.com';sub_filter '%%APP_VERSION%%' 'v2.3.1';-
sub_filter_once off;(允许多次替换,如一个页面含多个相同占位符) -
sub_filter_types text/html;(指定对 HTML 响应生效;如需替换内联 JS,可加application/javascript) -
sub_filter_last_modified off;(禁用 Last-Modified 头干扰缓存逻辑,推荐开启)
⚠️ 关键限制:sub_filter 仅对 未压缩(gzip off) 的响应生效。若启用了 gzip,需配合 gzip_vary off 或改用 gunzip on 解压后再处理(不推荐,影响性能)。
验证与调试技巧
替换是否生效,不能只看浏览器开发者工具的 Elements 标签页(它显示的是解析后 DOM),而应查看 Network → Response 原始内容:
- 访问页面,右键「检查」→ Network → 刷新 → 点击
index.html→ 查看 Response 标签页 - 确认占位符已被替换成目标值
- 若未生效,检查 Nginx 错误日志(
error_log /var/log/nginx/error.log debug;可开启 sub_filter 调试) - 注意:sub_filter 对大小写敏感,且不支持嵌套或转义,占位符中避免含空格或特殊符号

















