NGINX JavaScript 用 JS 扩展 NGINX 的能力

文章目录

  • [NGINX JavaScript: 用 JS 扩展 NGINX 的能力](#NGINX JavaScript: 用 JS 扩展 NGINX 的能力)

NGINX JavaScript: 用 JS 扩展 NGINX 的能力

nginx/njs 目前获得了 1,572 个 Star:

NGINX JavaScript(简称 NJS)是 NGINX 官方维护的一个动态模块,允许用户用 JavaScript 语法扩展 NGINX 的功能。

简单说,就是在 NGINX 配置里嵌入 JS 脚本,处理那些纯配置指令搞不定的逻辑。

核心能力

NJS 以动态模块形式加载,不需要重新编译 NGINX。它提供了两个模块:ngx_http_js_module 处理 HTTP 协议数据,ngx_stream_js_module 处理 TCP/UDP 等 stream 协议数据。

常见的使用场景包括:在请求到达上游服务器之前做访问控制和安全校验、修改响应头部、编写异步的内容处理器和过滤器。

官方基于 NJS 已经做了几个实际项目:NGINX Plus 的 OpenID Connect 认证扩展、SAML 认证的参考实现,以及直接从 NGINX Plus 暴露 Prometheus 指标端点的模块。

语法兼容性

NJS 的语言是 JavaScript 的子集,兼容 ES5 严格模式,同时扩展了部分 ES6 特性。前端或 Node.js 开发者基本可以直接上手,不需要学新的脚本语言。

安装

各主流 Linux 发行版可以通过包管理器直接安装:

Ubuntu/Debian 系统:

复制代码
sudo apt install nginx-module-njs

RHEL 及其衍生版本:

复制代码
sudo yum install nginx-module-njs

Alpine 系统:

复制代码
sudo apk add nginx-module-njs@nginx

安装完成后模块文件放在 /etc/nginx/modules/ 目录下。在 nginx.conf 的 main 上下文中加入 load_module 指令就能启用:

复制代码
load_module modules/ngx_http_js_module.so;
load_module modules/ngx_stream_js_module.so;

写一个 Hello World

创建一个 JS 文件放到 /etc/nginx/njs/ 目录:

javascript 复制代码
function hello(r) {
  r.return(200, "Hello world!\n");
}

export default {hello}

然后在 nginx.conf 中引用这个文件:

nginx 复制代码
js_path "/etc/nginx/njs/";
js_import main from http/hello.js;

server {
  listen 80;
  location / {
    js_content main.hello;
  }
}

重启 NGINX 后访问对应路径,就能看到返回的 Hello World。

命令行工具

NJS 自带一个 CLI 工具,可以做交互式 shell,也能直接处理 JS 文件或标准输入中的代码。不过由于独立运行,NGINX 相关的对象(如 HTTP 和 Stream)在 CLI 环境中不可用。

简单用法:

复制代码
$ njs
>> 2**3
8
>>

从源码构建

想从源码编译的话,需要先装好 gcc、make 以及 PCRE、zlib、SSL 等依赖库。然后分别克隆 NJS 和 NGINX 的代码仓库,在 NGINX 源码目录通过 configure 命令把 NJS 作为动态模块添加进去。

NJS 同时支持 QuickJS 引擎,构建时需要额外克隆 QuickJS 仓库并指定头文件和库路径。

兼容性和许可证

NJS 支持从 nginx-1.14 开始的所有 NGINX Open Source 版本,以及从 NGINX Plus R15 开始的所有 Plus 版本。部署环境覆盖容器、公有云和虚拟机。

项目使用 2-clause BSD 许可证,可以自由使用和修改。

INX Open Source 版本,以及从 NGINX Plus R15 开始的所有 Plus 版本。部署环境覆盖容器、公有云和虚拟机。

项目使用 2-clause BSD 许可证,可以自由使用和修改。