NJS 不能直接操作磁盘缓存文件,只能通过构造符合 purge 规则的请求路径,配合已启用 proxy_cache_purge 模块的 Nginx(如 OpenResty 或编译含该模块版本)实现前缀批量清理;关键前提是 cache_key 必须保留可识别路径结构(如 "$scheme$host$uri"),并严格校验输入、限制访问权限以保障安全。

使用 NJS(NGINX JavaScript)可以在 NGINX 运行时动态控制缓存行为,但需注意:NJS 本身不能直接操作磁盘上的 proxy_cache 或 fastcgi_cache 文件,它只能通过触发 NGINX 内置的缓存清理机制(如 proxy_cache_purge)或配合外部工具间接实现。真正可行的“对特定前缀批量擦除”,核心在于:利用 NJS 构建符合 NGINX purge 规则的请求路径,再由 NGINX 原生 purge 模块执行匹配删除。
确保 NGINX 已启用 cache purge 功能
NGINX 官方开源版默认不支持 proxy_cache_purge,必须使用支持 purge 的版本(如 OpenResty、Nginx Plus,或编译时添加 --with-http-cache-purge-module 的第三方模块)。确认方法:
- 运行
nginx -V 2>&1 | grep -o with-http-cache-purge-module,有输出即支持 - 在配置中检查是否存在类似
proxy_cache_purge $scheme$host$uri$is_args$args;的指令 - 若未启用,NJS 无法驱动任何缓存清除动作 —— 这是前提,不可跳过
用 NJS 生成带前缀匹配的 purge 请求路径
NJS 的作用是根据业务逻辑(如请求头、参数、URI)动态构造一个能命中目标缓存键前缀的 purge URI。例如,想清空所有以 /api/v2/users/ 开头的缓存,可让 NJS 返回该路径,并交由 NGINX purge 指令处理:
- 在
http块中定义 NJS 函数:
js_import http://example.com/njs/purge.js; js_set $purge_key purge.genPurgeKey;
- 在
purge.js中编写逻辑(示例):
function genPurgeKey(r) {
const uri = r.uri;
if (uri.startsWith('/admin/clear-prefix')) {
const prefix = r.args.prefix || '/api/v2/';
return prefix; // 返回 /api/v2/,将匹配所有以此开头的缓存 key
}
return ''; // 不触发 purge
}- 在 location 中调用 purge:
location ~ ^/admin/clear-prefix$ {
allow 127.0.0.1;
deny all;
proxy_cache_purge my_cache $scheme$host$purge_key$request_uri;
}⚠️ 注意:$request_uri 包含参数,实际 purge key 是 $scheme$host$purge_key$request_uri 的哈希结果;为覆盖前缀,建议 $purge_key 后不拼完整 URI,而仅设为目录路径(如 /api/v2/),并确保 cache key 定义中包含 $uri 且未截断层级。
配合 map + proxy_cache_key 实现可 purge 的缓存结构
能否按前缀清理,根本取决于 cache key 是否保留了可识别的层级信息。若原始 key 是 hash($request_uri),则无法前缀匹配。必须显式构造含路径前缀的 key:
- 在 cache 配置中定义明确的 key:
proxy_cache_key "$scheme$host$uri"; # ✅ 保留完整路径,支持 /api/v2/xxx 匹配
- 避免使用会破坏路径结构的 key,例如:
proxy_cache_key "$host$request_uri"; # ❌ 若 $request_uri 含参且顺序不定,影响一致性
- 推荐加一层 map 映射,将业务前缀标准化:
map $uri $cache_prefix {
~^/api/v2/users/ "/api/v2/users/";
~^/api/v2/posts/ "/api/v2/posts/";
default "/";
}
proxy_cache_key "$scheme$host$cache_prefix";这样 NJS 只需返回 /api/v2/users/,即可精准清除该前缀下全部缓存。
安全与生产注意事项
批量 purge 是高危操作,必须严格管控:
- 限制 purge 接口仅允许内网或认证后访问(如结合
auth_request或 IP 白名单) - 避免在 purge URI 中直接拼接用户输入;NJS 中应对
r.args.prefix做白名单校验(如正则匹配^/api/v[0-9]+/) - 不建议在高并发场景下频繁 purge 大量 key,可能引发 NGINX worker 阻塞;可考虑异步化(如写入队列,由后台任务轮询执行)
- OpenResty 用户可进一步用
resty.lock防止 purge 并发冲突,或用ngx.timer.at延迟执行
不复杂但容易忽略。


















