Модуль ngx_http_js_module

Пример конфигурации
Директивы
     js_body_filter
     js_content
     js_header_filter
     js_import
     js_include
     js_path
     js_set
     js_var
Аргумент запроса

Модуль ngx_http_js_module позволяет задавать обработчики location и переменных на njs — подмножестве языка JavaScript.

Инструкция по сборке и установке доступны здесь.

Пример конфигурации

Пример работает начиная с версии 0.4.0.

http {
    js_import http.js;

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

    server {
        listen 8000;

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

        location = /summary {
            return 200 $summary;
        }

        location = /hello {
            js_content http.hello;
        }
    }
}

The http.js file:

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!");
}

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

Директивы

Синтаксис: js_body_filter функция | модуль.функция [buffer_type=строка | буфер];
Умолчание:
Контекст: location, limit_except

Эта директива появилась в версии 0.5.2.

Задаёт функцию njs в качестве фильтра тела ответа. Функция фильтра вызывается для каждого блока данных тела ответа со следующими аргументами:

r
объект HTTP request
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_content функция | модуль.функция;
Умолчание:
Контекст: location, limit_except

Задаёт функцию njs в качестве обработчика содержимого location. Начиная с версии 0.4.0 можно ссылаться на функцию модуля.

Синтаксис: js_header_filter функция | модуль.функция;
Умолчание:
Контекст: location, limit_except

Эта директива появилась в версии 0.5.1.

Задаёт функцию njs в качестве фильтра заголовка ответа. Директива позволяет менять произвольные поля заголовка ответа.

Синтаксис: js_import модуль.js | имя_экспорта из модуль.js;
Умолчание:
Контекст: http

Эта директива появилась в версии 0.4.0.

Импортирует модуль, позволяющий задавать обработчики location и переменных на njs. Имя_экспорта является пространством имён при доступе к функциям модуля. Если имя_экспорта не задано, то пространством имён будет являться имя модуля.

js_import http.js;

В примере при доступе к экспорту в качестве пространства имён используется имя модуля http. Если импортируемый модуль экспортирует foo(), то для доступа используется http.foo.

Директив js_import может быть несколько.

Синтаксис: js_include файл;
Умолчание:
Контекст: http

Задаёт файл, позволяющий задавать обработчики location и переменных на 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, вместо неё следует использовать директиву js_import.

Синтаксис: js_path путь;
Умолчание:
Контекст: http

Эта директива появилась в версии 0.3.0.

Задаёт дополнительный путь для модулей njs.

Синтаксис: js_set $переменная функция | модуль.функция;
Умолчание:
Контекст: http

Задаёт функцию njs для указанной переменной. Начиная с 0.4.0 можно ссылаться на функцию модуля.

Функция вызывается в момент первого обращения к переменной для данного запроса. Точный момент вызова функции зависит от фазы, в которой происходит обращение к переменной. Это можно использовать для реализации дополнительной логики, не относящейся к вычислению переменной. Например, если переменная указана в директиве log_format, то её обработчик не будет выполняться до фазы записи в лог. Этот обработчик также может использоваться для выполнения процедур непосредственно перед освобождением запроса.

Синтаксис: js_var $переменная [значение];
Умолчание:
Контекст: http

Эта директива появилась в версии 0.5.3.

Объявляет перезаписываемую переменную. В качестве значения можно использовать текст, переменные и их комбинации. Переменная не перезаписывается после перенаправления, в отличие от переменных, созданных при помощи директивы set.

Аргумент запроса

Каждый HTTP-обработчик njs получает один аргумент, объект запроса.