<!-- review: finished -->

<a id="external-njs"></a>

# NJS

Модуль обеспечивает интеграцию языка программирования JavaScript в модель
обработки событий Angie и позволяет расширять функциональность сервера с помощью
скриптов на JavaScript. Состоит из двух модулей:

- [HTTP JS](https://angie.software//angie/docs/installation/external-modules/http_js.md#http-js) — для обработки HTTP-трафика;
- [Stream JS](https://angie.software//angie/docs/installation/external-modules/stream_js.md#stream-js) — для обработки TCP/UDP-трафика.

<a id="installation-19"></a>

## Установка

Для [установки](https://angie.software//angie/docs/installation/index.md#install-packages) модуля используйте один из
следующих пакетов:

- Angie: `angie-module-njs` или `angie-module-njs-light`;
- Angie PRO: `angie-pro-module-njs` или `angie-pro-module-njs-light`.

<a id="features-1"></a>

## Возможности

Модуль расширяет функциональность сервера с помощью скриптов на языке njs,
подмножестве JavaScript, позволяя реализовывать пользовательскую логику на
стороне сервера и многое другое:

- Сложные проверки контроля доступа и безопасности до того,
  как запрос достигнет проксируемого сервера.
- Манипулирование заголовками ответа.
- Написание гибких асинхронных обработчиков и фильтров контента.

Также доступна автономная утилита командной строки, которая может использоваться
независимо от сервера для разработки и отладки njs-скриптов.

<a id="loading-the-module-19"></a>

## Загрузка модуля

Загрузка модулей в контексте `main{}`:

```nginx
load_module modules/ngx_http_js_module.so;    # для HTTP
load_module modules/ngx_stream_js_module.so;  # для Stream
```

<a id="usage"></a>

## Использование

Подробная документация доступна в разделах отдельных модулей:

- [HTTP JS](https://angie.software//angie/docs/installation/external-modules/http_js.md#http-js)
- [Stream JS](https://angie.software//angie/docs/installation/external-modules/stream_js.md#stream-js)

<a id="security"></a>

## Безопасность

Модуль не выполняет динамический код, в особенности код, полученный из сети.
Единственный способ выполнить такой код с помощью njs — это настроить директиву
`js_import` в конфигурации сервера. JavaScript-код загружается однократно
при запуске сервера.

В модели угроз модуля JavaScript-код считается доверенным источником так же, как
конфигурационный файл и сертификаты сайтов. На практике это означает следующее:

- раскрытие содержимого памяти и другие проблемы безопасности, вызванные
  модификацией JavaScript-кода, не считаются проблемами безопасности,
  а рассматриваются как обычные ошибки;
- необходимо принимать меры по защите JavaScript-кода, используемого модулем;
- если в конфигурационном файле отсутствуют директивы `js_import`,
  сервер защищен от уязвимостей, связанных с JavaScript.

<a id="command-line-utility"></a>

## Утилита командной строки

Разрабатывать и отлаживать njs-скрипты помогает утилита командной строки
**njs**, которая устанавливается вместе с модулями. В отличие от ситуации
запуска модуля, работающего в составе Angie, объекты Angie (`HTTP` и
`Stream`) при использовании утилиты недоступны.

Примеры использования утилиты:

```console
$ echo "2**3" | njs -q
8

$ njs

>> globalThis
global {
 njs: njs {
  version: '0.3.9'
 },
 global: [Circular],
 process: process {
  argv: [
   '/usr/bin/njs'
  ],
...
```

<a id="preloaded-objects"></a>

## Предзагружаемые объекты

Для каждого входящего запроса модуль создает отдельную виртуальную машину. Это
дает множество преимуществ, таких как предсказуемое потребление памяти и
изоляция запросов. Однако, поскольку все запросы изолированы, если обработчику
запроса необходимо получить доступ к каким-либо данным, он должен прочитать их
самостоятельно. Это неэффективно, особенно когда объем данных велик.

Для решения этой проблемы был введен механизм предзагружаемых общих объектов.
Такие объекты создаются неизменяемыми и не имеют цепочек прототипов: их значения
не могут быть изменены, свойства не могут быть добавлены или удалены.

Вот несколько примеров работы с предзагружаемыми объектами в njs:

- Доступ к свойствам по имени:
  ```javascript
  preloaded_object.prop_name
  preloaded_object[prop_name]
  ```
- Перечисление свойств:
  ```javascript
  for (i in preloaded_object_name) {
        // ...
  }
  ```
- Применение немодифицирующих встроенных методов с помощью `call()`:
  ```javascript
  Array.prototype.filter.call(preloaded_object_name, ...)
  ```

<a id="api-reference"></a>

## Справочник API

Полный справочник всех объектов, методов и свойств njs:

- [Справочник API NJS](https://angie.software//angie/docs/configuration/njs-reference.md#njs-reference)

<a id="additional-information-20"></a>

## Дополнительная информация

- Официальный сайт: [https://nginx.org/ru/docs/njs/](https://nginx.org/ru/docs/njs/)
- Примеры использования: [https://github.com/nginx/njs-examples/](https://github.com/nginx/njs-examples/)
