sub_filter通过隐藏入口、拦截资源、劫持JS行为三步实现模块关闭:删除HTML节点与脚本、重写API路径、注入空函数,配合类型配置、禁用gzip及灰度开关确保生效。

直接用 sub_filter 关闭特定功能模块,本质是“隐藏+拦截”双管齐下:不改后端代码、不重启服务,靠 Nginx 在响应层做精准内容干预。
定位并移除前端功能入口
多数模块通过 HTML 中的 DOM 节点(如按钮、菜单项、路由链接)或 JS 初始化逻辑触发。可针对性删除其可见载体:
- 匹配并清空导航栏中的模块入口:
sub_filter '- 报表中心
' ''; - 移除页面底部加载的模块脚本标签:
sub_filter '<script src="/js/report-module.js"></script>' ''; - 若入口由 JS 动态注入,可替换初始化语句:
sub_filter 'initReportModule();' '';
阻断模块资源请求路径
即使前端残留代码,只要关键接口或静态资源被重写为 404 或空响应,模块即失效:
- 将模块 API 前缀统一替换成无效路径:
sub_filter '/api/v1/report/' '/_disabled_/'; - 对模块专属 CSS/JS 文件返回空内容:
sub_filter '/static/report.css' '/_empty.css';,再配一个location = /_empty.css { return 200 ""; } - 注意:需在
sub_filter_types中显式包含application/json和text/css等类型,否则 JSON 接口响应不会被处理
覆盖模块运行时行为(JS 层面)
针对已加载但尚未执行的 JS 逻辑,可用变量注入方式劫持关键函数:
- 在 HTML
或结尾注入屏蔽脚本:sub_filter '' '<script>window.initReportModule = function(){};</script>'; - 或替换整个模块定义语句:
sub_filter 'class ReportModule {' 'class ReportModule { disabled: true; constructor() {}';; - 确保
sub_filter_once off开启,避免只替换第一个匹配项;同时关闭 Gzip(proxy_set_header Accept-Encoding ""),否则压缩内容无法被解析替换
验证与灰度控制
上线前必须验证是否真正生效,且支持按需回滚:
- 用
curl -I检查响应头中Content-Encoding是否为空,确认未压缩 - 通过
map+if实现路径级开关:map $request_uri $disable_report { ~^/admin/ 0; ~^/user/ 1; default 0; },再在sub_filter行前加if ($disable_report) { ... } - 配合
add_header X-Feature-Status "report:disabled";便于前端或监控识别当前状态










