Nginx 的 JavaScript 魔力:njs 简介与实践(2026 年视角)
njs(NGINX JavaScript module)是 NGINX 官方推出的动态模块,让你可以用 JavaScript(ECMAScript 5.1 严格模式 + 部分 ES6+ 扩展)直接在 NGINX 内部编写逻辑,而无需编写 C 模块或依赖 Lua/OpenResty。
它极大提升了 NGINX 的可编程性,尤其适合:
- 复杂的访问控制、请求/响应头修改
- 轻量级 API 网关、认证、A/B 测试
- 子请求、异步内容生成、响应过滤
- 与现代 JS 生态(如 QuickJS 引擎)结合
2026 年最新版本(njs 0.9.5,2026年1月发布)已支持 QuickJS 引擎(完整 ES2023 兼容,包括模块、async generators、proxies、BigInt 等),性能提升显著(0.9.0 版本引擎性能提升 30%),Fetch API、WebCrypto、XML/Zlib 等模块更完善。
一、njs 的核心优势(对比 Lua/OpenResty)
| 项目 | njs (NGINX 官方) | OpenResty (Lua) | 选择建议(2026) |
|---|---|---|---|
| 语言 | JavaScript (ES5+ 部分 ES2023) | Lua | 团队熟悉 JS 首选 njs |
| 引擎 | QuickJS / 原生 njs(可选) | LuaJIT | QuickJS 更现代 |
| 模块加载 | 动态模块(无需重编译 NGINX) | 需要 OpenResty 发行版 | njs 更轻便 |
| 官方支持 | NGINX 官方维护 | 第三方 | 稳定性更高 |
| 生态 | Fetch、Crypto、XML、Zlib、共享字典 | 更丰富 Lua 库 | njs 够用且轻量 |
| 性能 | 高(QuickJS 优化后接近原生) | 极高(LuaJIT) | 日常场景差距小 |
| 学习曲线 | 低(前端/全栈开发友好) | 中(Lua 语法不同) | JS 开发者选 njs |
一句话总结:如果你团队偏好 JavaScript,想在原生 NGINX 上加“胶水”逻辑,而不是完整 API 网关,njs 是 2026 年最优雅的选择。
二、快速上手(安装 & Hello World)
1. 安装 njs(主流方式)
Debian/Ubuntu(官方仓库):
# 添加 NGINX 官方源(假设已加)
apt install nginx-module-njs
Docker(最推荐测试):
docker run -it --rm -p 8080:80 nginx:1.27 njs -V # 检查版本
# 或使用带 njs 的镜像
docker run -p 8080:80 -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro nginxinc/nginx-unprivileged:1.27-njs
从源码(支持 QuickJS):
参考 https://nginx.org/en/docs/njs/install.html
2. 最简单 Hello World
创建 http.js:
function hello(r) {
r.return(200, "Hello from njs! 🌟\n");
}
export default { hello };
nginx.conf 配置:
load_module modules/ngx_http_js_module.so; # 或 .dll
http {
js_import main from /etc/nginx/njs/http.js; # 路径根据实际情况
server {
listen 80;
location /hello {
js_content main.hello; # 调用函数
}
}
}
重载 NGINX:
nginx -s reload
curl http://localhost/hello
# 输出:Hello from njs! 🌟
三、2026 年常用 njs 能力 & 实战示例
1. 请求头/响应头操作(最常见)
function addSecurityHeaders(r) {
r.headersOut['X-Content-Type-Options'] = 'nosniff';
r.headersOut['X-Frame-Options'] = 'DENY';
r.headersOut['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains';
r.return(200);
}
function logRequest(r) {
r.log(`Request from ${r.remoteAddress} to ${r.uri}`);
}
2. 简单 API 网关 + 认证(Token 校验)
async function authGateway(r) {
const token = r.headersIn['Authorization'] || '';
if (!token.startsWith('Bearer ')) {
r.return(401, 'Missing or invalid token');
return;
}
const cleanToken = token.slice(7);
try {
// 假设调用外部 auth 服务(njs 支持 async/await + fetch)
const resp = await ngx.fetch('https://auth.example.com/verify', {
method: 'POST',
headers: { 'Authorization': `Bearer ${cleanToken}` }
});
if (resp.status !== 200) {
r.return(403, 'Forbidden');
return;
}
// 透传上游
r.subrequest('/upstream' + r.uri, { method: r.method });
} catch (e) {
r.return(500, 'Internal auth error');
}
}
配置:
location /api/ {
js_content main.authGateway;
proxy_pass http://backend;
}
3. 响应体过滤(替换内容)
function replaceText(r) {
r.sendHeader();
r.on('upload', (data) => {
// 简单字符串替换(生产慎用,性能考虑)
const modified = data.replace(/old-brand/g, 'new-brand');
r.send(modified);
});
r.finish();
}
4. 定时任务(js_periodic,新功能)
http {
js_periodic main.cleanup interval=300s; # 每5分钟执行一次
}
# http.js
function cleanup() {
// 清理共享字典、日志等
ngx.shared.my_cache.clear?.();
}
5. 共享字典 + 状态保持(rate limit 示例)
http {
js_shared_dict_zone zone=rate_limit:1m;
location /limited {
js_content main.rateLimit;
}
}
function rateLimit(r) {
const key = r.remoteAddress;
const limit = 100; // 每分钟100次
const dict = ngx.shared.rate_limit;
let count = dict.get(key) || 0;
count = parseInt(count) + 1;
if (count > limit) {
r.return(429, 'Too Many Requests');
return;
}
dict.set(key, count, 60); // 60秒过期
r.return(200, `OK, count: ${count}`);
}
四、njs 2026 年最新亮点(0.9.x 系列)
- QuickJS 引擎(ES2023 完整支持):async generators、Proxy、BigInt、模块语法
- ngx.fetch() 增强:HTTP forward proxy、keepalive 支持
- js_periodic:定时 JS 执行(http/stream 均支持)
- 共享字典持久化:state file 支持
- 性能:0.9.0 引擎提升 30%,QuickJS 模式更现代
官方示例仓库(强烈推荐克隆):https://github.com/nginx/njs-examples
五、注意事项 & 最佳实践(2026 生产建议)
- 性能:njs 轻量但非 JIT,避免复杂计算放 JS 中
- 调试:用
njsCLI 交互式调试(docker run nginx njs)
docker run -it nginx njs
>> r = {uri:'/test'}; hello(r)
- 模块化:用
export default { fn1, fn2 }组织代码 - 安全:不要在 njs 中处理敏感逻辑(密钥等),优先 upstream
- 兼容:QuickJS 模式下 ES2023 语法可用,但旧 njs 引擎仍为 ES5+ 兼容
- 监控:用 NGINX stub_status 或 Prometheus exporter 监控 JS 执行耗时
njs 让 NGINX 从“高性能反代”进化成“可编程边缘计算节点”,是 2026 年构建轻量 API 网关、零信任入口、动态路由的利器。
如果你想深入某个场景(如完整 API 网关、JWT 校验、WAF 规则引擎、A/B 测试),贴出需求,我可以直接给出更详细的 njs 代码 + 配置。