ngx_http_js_module 模块

ngx_http_js_module 模块用于在 njs 中实现 location 和变量处理程序 —— 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

";

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

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

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

    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 指令

语 法:js_body_filter function | module.function [buffer_type=string | buffer];
默认值:—
上下文:location, limit_except

该指令出现在 0.5.2 版本中。

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

  • r  HTTP 请求对象

  • data  传入的数据块,可能是字符串或缓冲区,具体取决于 buffer_type 值,默认情况下是字符串。

  • flags  具有以下属性的对象:

    • last  一个布尔值,如果数据是最后一个缓冲区,则为真。

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

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

要停止过滤(以下数据块将传递给客户端而不调用 js_body_filter),可以使用 r.done()。

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

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

js_content 指令

语 法:js_content function | module.function;
默认值:—
上下文:location, limit_except

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

js_fetch_ciphers 指令

语 法:js_fetch_ciphers ciphers;
默认值:js_fetch_ciphers HIGH:!aNULL:!MD5;
上下文:http, server, location

该指令出现在 0.7.0 版中。

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

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

js_fetch_protocols 指令

语 法: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_trusted_certificate 指令

语 法:js_fetch_trusted_certificate file;
默认值:—
上下文:http, server, location

该指令出现在 0.7.0 版中。

指定具有 PEM 格式的可信 CA 证书的文件,用于通过 Fetch API 验证 HTTPS 证书

js_fetch_verify_depth 指令

语 法:js_fetch_verify_depth number;
默认值:js_fetch_verify_depth 100;
上下文:http, server, location

该指令出现在 0.7.0 版中。

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

js_header_filter 指令

语 法:js_header_filter function | module.function;
默认值:—
上下文:location, limit_except

该指令出现在 0.5.1 版中。

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

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

js_import 指令

语 法:js_import module.js | export_name from module.js;
默认值:—
上下文:http

该指令出现在 0.4.0 版中。

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

js_import http.js;

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

可以指定几个 js_import 指令。

js_include 模块

语 法:js_include file;
默认值:—
上下文:http

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

nginx.conf:

js_include http.js;
location   /version {
    js_content version;
}

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

该指令自 0.4.0 起已弃用,应改用 js_import 指令。

js_path 指令

语 法:js_path path;
默认值:—
上下文:http

该指令出现在 0.3.0 版中。

为 njs 模块设置附加路径。

js_set 指令

语 法:js_set $variable function | module.function;
默认值:—
上下文:http

为指定的变量设置一个 njs 函数。从 0.4.0 开始,可以引用模块函数。

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

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

js_var 指令

语 法:js_var $variable [value];
默认值:—
上下文:http

该指令出现在 0.5.3 版中。

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

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号