模块 ngx_http_js_module

Example Configuration
Directives
     js_body_filter
     js_content
     js_fetch_buffer_size
     js_fetch_ciphers
     js_fetch_max_response_buffer_size
     js_fetch_protocols
     js_fetch_timeout
     js_fetch_trusted_certificate
     js_fetch_verify
     js_fetch_verify_depth
     js_header_filter
     js_import
     js_include
     js_path
     js_periodic
     js_preload_object
     js_set
     js_shared_dict_zone
     js_var
Request Argument

ngx_http_js_module模块用于在njs  (JavaScript 语言的子集)中实现位置和变量处理程序。

此处 提供下载和安装说明 。

配置示例

该示例从 0.4.0开始运行。

http {
    js_import http.js;

    js_set $foo     http.foo;
    js_set $summary http.summary;
    js_set $hash    http.hash;

    resolver 10.0.0.1;

    server {
        listen 8000;

        location / {
            add_header X-Foo $foo;
            js_content http.baz;
        }

        location = /summary {
            return 200 $summary;
        }

        location = /hello {
            js_content http.hello;
        }

        # since 0.7.0
        location = /fetch {
            js_content                   http.fetch;
            js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
        }

        # since 0.7.0
        location = /crypto {
            add_header Hash $hash;
            return     200;
        }
    }
}

http.js文件:

function foo(r) {
    r.log("hello from foo() handler");
    return "foo";
}

function summary(r) {
    var a, s, h;

    s = "JS summary\n\n";

    s += "Method: " + r.method + "\n";
    s += "HTTP version: " + r.httpVersion + "\n";
    s += "Host: " + r.headersIn.host + "\n";
    s += "Remote Address: " + r.remoteAddress + "\n";
    s += "URI: " + r.uri + "\n";

    s += "Headers:\n";
    for (h in r.headersIn) {
        s += "  header '" + h + "' is '" + r.headersIn[h] + "'\n";
    }

    s += "Args:\n";
    for (a in r.args) {
        s += "  arg '" + a + "' is '" + r.args[a] + "'\n";
    }

    return s;
}

function baz(r) {
    r.status = 200;
    r.headersOut.foo = 1234;
    r.headersOut['Content-Type'] = "text/plain; charset=utf-8";
    r.headersOut['Content-Length'] = 15;
    r.sendHeader();
    r.send("nginx");
    r.send("java");
    r.send("script");

    r.finish();
}

function hello(r) {
    r.return(200, "Hello world!");
}

// since 0.7.0
async function fetch(r) {
    let results = await Promise.all([ngx.fetch('https://nginx.org/'),
                                     ngx.fetch('https://nginx.org/en/')]);

    r.return(200, JSON.stringify(results, undefined, 4));
}

// since 0.7.0
async function hash(r) {
    let hash = await crypto.subtle.digest('SHA-512', r.headersIn.host);
    r.setReturnValue(Buffer.from(hash).toString('hex'));
}

export default {foo, summary, baz, hello, fetch, hash};

指令

句法: js_body_filter function | module.function [buffer_type=string | buffer];
默认:
语境: location, if in location,limit_except

该指令出现在0.5.2版本中。

将 njs 函数设置为响应正文过滤器。使用以下参数为响应正文的每个数据块调用过滤器函数:

r
HTTP请求对象
data
传入的数据块,可能是字符串或缓冲区,具体取决于buffer_type值,默认情况下是字符串。
flags
具有以下属性的对象:
last
布尔值,如果数据是最后一个缓冲区,则为 true。

过滤器函数可以通过调用将其自己的输入数据块的修改版本传递给下一个主体过滤器 r.sendBuffer()。例如,要转换响应正文中的所有小写字母:

function filter(r, data, flags) {
    r.sendBuffer(data.toLowerCase(), flags);
}

可以使用 停止过滤(后续数据块将被传递到客户端而不调用js_body_filter) 。r.done()

如果过滤器函数更改了响应正文的长度,则需要清除“Content-Length”响应标头(如果有)以强制执行 js_header_filter 分块传输编码。

由于js_body_filter处理程序立即返回其结果,因此它仅支持同步操作。 因此,不支持 r.subrequest()setTimeout()等异步操作 。

0.7.7开始,该指令可以在if块 内指定 。

句法: js_content function | module.function;
默认:
语境: location, if in location,limit_except

将 njs 函数设置为位置内容处理程序。从0.4.0开始,可以引用模块函数。

0.7.7开始,该指令可以在if块 内指定 。

句法: js_fetch_buffer_size size;
默认:
js_fetch_buffer_size 16k;
语境: http, server,location

该指令出现在 0.7.4 版本中。

设置用于使用Fetch APIsize进行读写的缓冲区。

句法: js_fetch_ciphers ciphers;
默认:
js_fetch_ciphers HIGH:!aNULL:!MD5;
语境: http, server,location

该指令出现在 0.7.0 版本中。

指定使用Fetch API 为 HTTPS 请求启用的密码。密码以 OpenSSL 库可以理解的格式指定。

可以使用“ ”命令查看完整列表openssl ciphers

句法: js_fetch_max_response_buffer_size size;
默认:
js_fetch_max_response_buffer_size 1m;
语境: http, server,location

该指令出现在 0.7.4 版本中。

设置使用Fetch APIsize收到的响应的 最大值。

句法: js_fetch_protocols [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];
默认:
js_fetch_protocols TLSv1 TLSv1.1 TLSv1.2;
语境: http, server,location

该指令出现在 0.7.0 版本中。

使用Fetch API 为 HTTPS 请求启用指定协议。

句法: js_fetch_timeout time;
默认:
js_fetch_timeout 60s;
语境: http, server,location

该指令出现在 0.7.4 版本中。

定义Fetch API 读写超时。超时仅在两个连续的读/写操作之间设置,而不是在整个响应中设置。如果在此时间内没有数据传输,则连接被关闭。

句法: js_fetch_trusted_certificate file;
默认:
语境: http, server,location

该指令出现在 0.7.0 版本中。

指定file具有 PE​​M 格式的可信 CA 证书,用于 通过Fetch API验证 HTTPS 证书。

句法: js_fetch_verify on | off;
默认:
js_fetch_verify on;
语境: http, server,location

该指令出现在 0.7.4 版本中。

启用或禁用使用Fetch API 验证 HTTPS 服务器证书。

句法: js_fetch_verify_depth number;
默认:
js_fetch_verify_depth 100;
语境: http, server,location

该指令出现在 0.7.0 版本中。

使用Fetch API 设置 HTTPS 服务器证书链中的验证深度。

句法: js_header_filter function | module.function;
默认:
语境: location, if in location,limit_except

该指令出现在 0.5.1 版本中。

将 njs 函数设置为响应标头过滤器。该指令允许更改响应标头的任意标头字段。

由于js_header_filter处理程序立即返回其结果,因此它仅支持同步操作。 因此,不支持 r.subrequest()setTimeout()等异步操作 。

0.7.7开始,该指令可以在if块 内指定 。

句法: js_import module.js | export_name from module.js;
默认:
语境: http, server,location

该指令出现在 0.4.0 版本中。

导入一个在 njs 中实现位置和变量处理程序的模块。export_name用作访问模块函数的命名空间。如果export_name未指定,模块名称将用作命名空间。

js_import http.js;

在这里,模块名称http在访问导出时用作命名空间。如果导入的模块导出foo(), http.foo用于引用它。

js_import可以指定 多个指令。

从0.7.7server开始,可以在和location级别 上指定该指令 。

句法: js_include file;
默认:
语境: http

指定在 njs 中实现位置和变量处理程序的文件:

nginx.conf:
js_include http.js;
location   /version {
    js_content version;
}

http.js:
function version(r) {
    r.return(200, njs.version);
}

该指令在0.4.0 版本中已过时 ,并在0.7.1 版本中被删除 。应改用 js_import指令。

句法: js_path path;
默认:
语境: http, server,location

该指令出现在0.3.0版本中。

为 njs 模块设置附加路径​​。

从0.7.7server开始,可以在和location级别 上指定该指令 。

句法: js_periodic function | module.function [interval=time] [jitter=number] [worker_affinity=mask];
默认:
语境: location

该指令出现在 0.8.1 版本中。

指定定期运行的内容处理程序。该处理程序接收一个 会话对象 作为其第一个参数,它还可以访问全局对象,例如 ngx

可选interval参数设置两次连续运行之间的时间间隔,默认情况下为 5 秒。

可选jitter参数设置位置内容处理程序将随机延迟的时间,默认情况下没有延迟。

默认情况下,js_handler在工作进程 0 上执行。可选worker_affinity参数允许指定应在其中执行位置内容处理程序的特定工作进程。每个工作进程集由允许的工作进程的位掩码表示。该all掩码允许处理程序在所有工作进程中执行。

例子:

example.conf:

location @periodics {
    # to be run at 1 minute intervals in worker process 0
    js_periodic main.handler interval=60s;

    # to be run at 1 minute intervals in all worker processes
    js_periodic main.handler interval=60s worker_affinity=all;

    # to be run at 1 minute intervals in worker processes 1 and 3
    js_periodic main.handler interval=60s worker_affinity=0101;

    resolver 10.0.0.1;
    js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}

example.js:

async function handler(s) {
    let reply = await ngx.fetch('https://nginx.org/en/docs/njs/');
    let body = await reply.text();

    ngx.log(ngx.INFO, body);
}

句法: js_preload_object name.json | name from file.json;
默认:
语境: http, server,location

该指令出现在0.7.8版本中。

在配置时 预加载 不可变对象。使用name全局变量的名称,通过该名称可以在 njs 代码中使用该对象。如果name未指定,则将使用文件名。

js_preload_object map.json;

此处,map在访问预加载的对象时,将 用作名称。

js_preload_object可以指定 多个指令。

句法: js_set $variable function | module.function;
默认:
语境: http, server,location

为指定functionvariable. 从0.4.0开始,可以引用模块函数。

当针对给定请求第一次引用变量时,将调用该函数。确切的时刻取决于 引用变量的阶段。这可以用来执行一些与变量求值无关的逻辑。例如,如果仅在 log_format指令中引用该变量,则其处理程序直到日志阶段才会执行。该处理程序可用于在释放请求之前进行一些清理。

由于js_set处理程序立即返回其结果,因此它仅支持同步操作。 因此,不支持 r.subrequest()setTimeout()等异步操作 。

从0.7.7server开始,可以在和location级别 上指定该指令 。

句法: js_shared_dict_zone zone=name:size [timeout=time] [type=string|number] [evict];
默认:
语境: http

该指令出现在0.8.0版本中。

设置共享内存区域的namesize,以保持工作进程之间共享键值字典

默认情况下,共享字典使用字符串作为键和值。可选type参数允许将值类型重新定义为数字。

可选timeout参数设置从区域中删除所有共享字典条目后的时间。

当区域存储耗尽时,可选evict参数将删除最旧的键值对。

例子:

example.conf:
    # Creates a 1Mb dictionary with string values,
    # removes key-value pairs after 60 seconds of inactivity:
    js_shared_dict_zone zone=foo:1M timeout=60s;

    # Creates a 512Kb dictionary with string values,
    # forcibly removes oldest key-value pairs when the zone is exhausted:
    js_shared_dict_zone zone=bar:512K timeout=30s evict;

    # Creates a 32Kb permanent dictionary with number values:
    js_shared_dict_zone zone=num:32k type=number;

example.js:
    function get(r) {
        r.return(200, ngx.shared.foo.get(r.args.key));
    }

    function set(r) {
        r.return(200, ngx.shared.foo.set(r.args.key, r.args.value));
    }

    function del(r) {
        r.return(200, ngx.shared.bar.delete(r.args.key));
    }

    function increment(r) {
        r.return(200, ngx.shared.num.incr(r.args.key, 2));
    }

句法: js_var $variable [value];
默认:
语境: http, server,location

该指令出现在0.5.3版本中。

声明一个可写 变量。该值可以包含文本、变量及其组合。与使用set指令创建的变量不同,该变量在重定向后不会被覆盖 。

从0.7.7server开始,可以在和location级别 上指定该指令 。

请求参数

每个 HTTP njs 处理程序都会接收一个参数,即请求 对象