nginx njs: установка модуля, настройка js_set и применение через reload для создания переменных JavaScript

Уведомление о партнёрских ссылках v3.1
Уведомление о партнёрских ссылках v3.2 (мобильная версия)
Тестовая среда Семейство RHELAlmaLinux 9.8Nginx 1.28 + Apache 2.4njs 0.9.4WP Rocket 3.23.5.1Проверено 2026-10-17

nginx njs — официальный модуль nginx, который обрабатывает запросы или создаёт значения переменных функциями JavaScript прямо в конфигурации nginx. На сервере с конфигурацией Nginx + Apache, чтобы выровнять регистр URL запросов, чего нельзя сделать одной конфигурацией nginx, модуль njs был установлен в той же версии, что и установленный nginx, а переменная, созданная через js_set, подставлена в путь к файлу кэша и применена через reload без перезапуска.

Функция из примера — одна строка, переводящая процентное кодирование корейских URL в нижний регистр; переменные из значений заголовков или аргументов объекта запроса создаются так же.

1️⃣ Что такое nginx njs: модуль, расширяющий nginx с помощью JavaScript

njs — не самостоятельная среда выполнения JavaScript, как Node.js: у него нет стартового скрипта и собственного цикла событий, код выполняется, только когда nginx вызывает указанную в конфигурации функцию, после чего обработка возвращается к nginx.

Точки, где nginx вызывает функции JavaScript, определены заранее: этапы обработки HTTP-запросов и ответов, этапы обработки сессий TCP·UDP, вычисление значений переменных и периодические таймеры. Функция читает URL, заголовки и аргументы из объекта запроса, который передаёт nginx, и возвращает результат как ответ или значение переменной.

Со стороны HTTP [js_import] загружает файл скрипта, [js_set] создаёт значение переменной, [js_content] — тело ответа, а [js_header_filter] и [js_body_filter] изменяют заголовки и тело ответа. В этой настройке использованы две директивы: [js_import] и [js_set].

🧭 Где nginx вызывает функции njs
Поясняющая схема
📌 Точка вызова
📥 Запрос
🖥️ nginx
Этап обработки · точка, заданная в конфигурации
js_setВычисление значения переменной
js_contentТело ответа
js_header_filter · js_body_filterИзменение заголовков · тела ответа
Вызов→
📜 Функция njs
Объект запроса от nginx
Чтение URL · заголовков · аргументов
↩️ Возврат как значение переменной
↩️ Возврат как ответ
↩️ Возврат как изменённые заголовки · тело
❌ Не запускается сам по себе, как Node.jsНет стартового скрипта · нет собственного цикла событий
Возврат→
🖥️ nginx
Продолжает обработку
Значение переменнойПрименено здесь · подставлено в путь к файлу кэша
Тело ответаОтвет телом, созданным функцией
Заголовки · тело ответаОтвет с изменёнными заголовками и телом
📤 Ответ
[js_set] вызывает функцию в момент, когда nginx вычисляет значение переменной; возвращённое функцией значение становится значением переменной, и обработка возвращается к nginx.
[js_content] вызывает функцию в момент создания тела ответа, и nginx отправляет ответ, который функция построила по объекту запроса.
[js_header_filter] и [js_body_filter] вызывают функцию на этапе отправки ответа, чтобы изменить его заголовки и тело; после этого обработка возвращается к nginx.

Стандартный движок модуля njs реализует ECMAScript 5.1 (strict mode) с частью возможностей ECMAScript 6 и новее. Обработка строк на уровне замены по регулярным выражениям и функций работает в этих пределах.

2️⃣ Когда нужен njs: значения переменных, которые не изменить одной конфигурацией nginx

Плагин WordPress WP Rocket называет папки кэша записей с корейскими URL в процентном кодировании нижнего регистра, а браузеры запрашивают тот же URL, закодированный в верхнем регистре. На этом сервере работает сайт WordPress.

Если nginx строит путь к файлу кэша по URL запроса как есть, регистр не совпадает, файл не находится, и запрос уходит в Apache и PHP.

Одной конфигурацией nginx это значение в нижний регистр не перевести. [map] лишь выбирает одно из заданных значений и не преобразует строки, а до установки ни в выводе [nginx -V], ни в папке модулей не было модулей perl или lua.

Если менять нужно лишь несколько URL, справится и таблица соответствий [map], но её придётся пересобирать и делать reload при каждой новой записи. Когда каждый URL нужно преобразовать по одному правилу, одна функция [js_set] охватывает и URL новых записей, меток и рубрик.

[perl_set] из модуля perl тоже можно использовать в той же точке, и в репозитории есть парный nginx пакет, но официальная документация nginx называет модуль perl экспериментальным.

3️⃣ Установка nginx njs: в той же версии, что и установленный nginx

Установка только по имени пакета модуля выглядит так, будто добавится лишь njs, но последний njs в репозитории требует последний nginx, поэтому nginx тоже обновится. При проверке перед установкой команда установки без версии показала план обновления nginx с 1.28.0 до 1.30.6.

Поэтому сначала проверьте версию установленного nginx.

rpm -q nginx
nginx-1.28.0-1.el9.ngx.x86_64

В репозитории для каждой версии nginx есть свой парный пакет njs; в номере версии часть до + — версия nginx, а часть после — версия njs.

dnf list --showduplicates nginx-module-njs | grep '1.28.0+'
nginx-module-njs.x86_64         1:1.28.0+0.9.4-1.el9.ngx           @nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.8.10-1.el9.ngx          nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.0-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.1-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.2-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.3-1.el9.ngx           nginx-stable
nginx-module-njs.x86_64         1:1.28.0+0.9.4-1.el9.ngx           nginx-stable

С nginx 1.28.0 в паре шесть версий — от 0.8.10 до 0.9.4, а верхняя строка @nginx-stable — уже установленная версия. Устанавливается самая новая из них, 0.9.4, с полным номером версии.

dnf install nginx-module-njs-1:1.28.0+0.9.4-1.el9.ngx

Какую версию nginx требует установленный пакет, можно проверить через rpm.

rpm -q --requires nginx-module-njs | grep nginx
nginx-r1.28.0
rpm -ql nginx-module-njs | grep -v build-id
/usr/bin/njs
/usr/lib64/nginx/modules/ngx_http_js_module-debug.so
/usr/lib64/nginx/modules/ngx_http_js_module.so
/usr/lib64/nginx/modules/ngx_stream_js_module-debug.so
/usr/lib64/nginx/modules/ngx_stream_js_module.so
/usr/share/doc/nginx-module-njs
/usr/share/doc/nginx-module-njs/CHANGES
/usr/share/doc/nginx-module-njs/COPYRIGHT

Установлены HTTP-модуль, модуль stream для TCP·UDP, отладочная версия каждого из них и инструмент командной строки njs. В этой настройке загружается только один файл — HTTP-модуль [ngx_http_js_module.so].

4️⃣ Настройка js_set: от загрузки модуля до пути к файлу кэша

Установка пакета не заставляет nginx загружать модуль автоматически: в самом верху nginx.conf нужна строка [load_module]. Согласно официальной документации, [load_module] — директива контекста main, поэтому она размещается вне блоков events·http.

📂 /etc/nginx/Папка конфигурации
nginx.confload_module в самом верху — загрузка модуля
njs/rocket.jsФункция lc — в нижний регистр только процентное кодирование
conf.d/
rocket-njs.confБлок http — js_import · js_set
example.com.confБлок server — $rocket_uri в пути к файлу кэша
# самый верх /etc/nginx/nginx.conf (вне блоков events·http)
load_module modules/ngx_http_js_module.so;

Функция преобразования хранится в отдельном от конфигурации файле .js, а конфигурация nginx загружает функцию, экспортированную через export default в последней строке.

// /etc/nginx/njs/rocket.js — в нижний регистр только процентное кодирование %XX
function lc(r) {
    return r.variables.request_uri.replace(/%[0-9A-F]{2}/g, function (m) { return m.toLowerCase(); });
}
export default { lc };

Функция читает переменную [request_uri] из объекта запроса r, переводит в нижний регистр только два символа после знака процента, если они заглавные, и возвращает результат. Латинские буквы не трогаются, поэтому английские URL с заглавными буквами не меняются; это совпадает с правилом, по которому WP Rocket называет папки кэша.

# внутри блока http (файл .conf в conf.d)
js_import rkt from /etc/nginx/njs/rocket.js;
js_set $rocket_uri rkt.lc;

rkt в [js_import] — имя для вызова функций внутри модуля, а [js_set] превращает результат этой функции в переменную [$rocket_uri]. Согласно официальной документации, функция выполняется при первом обращении к переменной в запросе и поддерживает только синхронную обработку.

# блок server — $request_uri в пути к файлу кэша заменяется на $rocket_uri
set $rocket_file '/wp-content/cache/wp-rocket/example.com${rocket_uri}index$rocket_mobile-https.html';

Изменена только эта одна строка, строящая путь к файлу кэша; условия, исключающие из кэша cookie входа, запросы с параметрами и POST-запросы, остаются прежними.

5️⃣ Применение и проверка: журнал ошибок и заголовки ответа после reload

Сначала выполните проверку конфигурации, а если она пройдёт — reload.

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl reload nginx

Новая строка [load_module] применилась через reload без перезапуска. В журнале ошибок осталась строка об инициализации виртуальной машины njs, ошибок JavaScript не было.

grep 'js vm init' /var/log/nginx/error.log | head -1
2026/10/17 18:21:35 [notice] 27992#27992: js vm init njs: 0000559FDF6D0E00

njs в конце строки — имя используемого движка. Та же строка пишется и при проверке конфигурации через [nginx -t], поэтому сверяйте её со временем reload.

curl -sI 'https://example.com/-/' | grep -i 'x-rocket\|content-type'
content-type: text/html
x-rocket-nginx-serving-file: HIT

Даже для корейского URL, закодированного в верхнем регистре, появился заголовок, показывающий, что nginx отдал файл кэша. Запросы с параметрами или cookie входа и POST-запросы после изменения по-прежнему уходили в PHP без этого заголовка.

6️⃣ Откат njs и обновление nginx

Для отката замените [$rocket_uri] в пути к файлу кэша обратно на [$request_uri], уберите файл конфигурации [js_import]·[js_set] и строку [load_module], затем выполните проверку конфигурации и reload.

# блок server — обратно к исходной переменной
set $rocket_file '/wp-content/cache/wp-rocket/example.com${request_uri}index$rocket_mobile-https.html';

Пакет можно оставить: без строки [load_module] nginx его не загружает, поэтому удаляйте пакет, только если хотите убрать его полностью.

dnf remove nginx-module-njs

При обновлении nginx пакет njs тоже должен обновиться до версии, парной новому nginx. Перед обновлением проверьте через [dnf list --showduplicates], есть ли в репозитории пара njs для новой версии nginx.

🔢 FAQ & рекомендуемые материалы

Официальная документация nginx с версии 1.0.0 отмечает стандартный движок njs как устаревший (deprecated) и рекомендует для новых настроек движок QuickJS с поддержкой ES2023. Движок выбирается директивой [js_engine qjs], доступной с версии 0.8.6. Установка 0.9.4 в этой статье работала на стандартном движке njs, переход на QuickJS не проверялся.

Это самостоятельный инструмент командной строки для разработки и отладки кода njs без nginx (согласно официальной документации). Он устанавливается вместе с пакетом nginx-module-njs, а проверка версии через [njs -v] показывает 0.9.4 — ту же, что у модуля.

Если обрабатываются только HTTP-запросы, достаточно одного [ngx_http_js_module]. В пакете есть и [ngx_stream_js_module] для сессий TCP·UDP, а официальная документация по установке советует загружать нужный из двух модулей через [load_module].

🧭 Статьи о WP Rocket Статьи: 16 · Инструменты: 3
📋 Настройка WP Rocket 📄 WP Rocket MCP Server 📄 WP Rocket и URL на корейском 📄 nginx njs 📄 Многоязычный кеш WP Rocket 📄 gclid и кеш
📄 Тест скорости WP Rocket 📝 Плагины кеширования и оптимизации 📝 Пример ускорения сайта
📋 Кеш: определение и все области применения 📄 Кеш сайта & внутренний кеш сервера
📋 Лучший хостинг: TOP 7 📄 Быстрый хостинг 2026
🛠️ Определение WordPress 🛠️ WHOIS-проверка домена 🛠️ Мой IP
Что такое WP Rocket: пять утверждений из статьи с рекомендацией FlyingPress в сравнении с официальными экранами и замерами на сервере
WordPress · WP Rocket
Что такое WP Rocket: основные функции, плюсы и минусы универсального плагина кеширования
Как WP Rocket отдаёт страницы из файлов кеша и сколько он стоит.
Читать →Текущая статья
Настройка WP Rocket: базовые параметры каждого меню и промокод на 20%
WordPress · WP Rocket
Настройка WP Rocket: базовые параметры каждого меню и промокод на 20%
Базовые настройки WP Rocket по каждому меню и цены.
Читать →Текущая статья
WP Rocket MCP Server: управление кешем и настройками через ИИ-инструменты
WordPress · MCP
WP Rocket MCP Server: управление кешем и настройками через ИИ-инструменты
Как управлять кешем и настройками WP Rocket из ИИ-инструментов.
Читать →Текущая статья
Схема прохождения запросов с корейскими URL в WP Rocket
WordPress · WP Rocket
WP Rocket и URL на корейском
Почему nginx не находит файл кеша из-за регистра букв в кодировке запросов с корейскими адресами и как исправить это с помощью njs.
Читать →Текущая статья
Схема переменных nginx njs и путей к файлам кеша
Server · nginx
nginx njs: установка модуля, настройка js_set и применение через reload для создания переменных JavaScript
Как установить модуль njs, который создаёт переменные с помощью функций JavaScript внутри конфигурации nginx, и применить переменные js_set через reload.
Читать →Текущая статья
Схема сохранения записи при многоязычном кеше WP Rocket
WordPress · WP Rocket
Многоязычный кеш WP Rocket
Почему при сохранении черновика кеш переводов удаляется вместе со всей папкой языка, и код, который это предотвращает.
Читать →Текущая статья
Как запрос с рекламным параметром при отсутствии копии в CDN уходит на исходный сервер, проходит из nginx в Apache, а WP Rocket отбрасывает рекламный параметр и отвечает тем же файлом кеша
Server · кеш
gclid и кеш: запрос из клика по рекламе, ключ кеша страницы и замер первого байта
Замер по времени до первого байта: как запрос gclid в конце адреса из клика по рекламе игнорируется и ответ отдаётся из файла кеша адреса без запроса.
Читать →Текущая статья
🪐ИсточникиОфициальные документы: 3

ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Докажите, что вы человек: 8   +   1   =