Настройка приложения Node.js для работы в среде Ubuntu 18.04

Node.js — среда исполнения JavaScript с открытым исходным кодом, предназначенная для построения серверных и сетевых приложений. Данная платформа работает в операционных системах Linux, macOS, FreeBSD и Windows. Хотя вы можете запускать приложения Node.js через командную строку, этот обучающий модуль посвящен их запуску в качестве службы. Это означает, что они будут перезапускаться при перезагрузке системы или неисправности, и что их можно безопасно использовать в производственной среде.
В этом обучающем модуле вы научитесь создавать готовую производственную среду Node.js на одном сервере Ubuntu 18.04. Этот сервер будет выполнять приложение Node.js под управлением PM2 и предоставлять пользователям безопасный доступ к приложению через обратный прокси-сервер Nginx. Сервер Nginx обеспечивает поддержку HTTPS с использованием бесплатного сертификата от Let’s Encrypt.
Предварительные требования
Этот обучающий модуль предполагает, что у вас имеется следующее:
- Сервер Ubuntu 18.04, настроенный в соответствии с указаниями обучающего модуля Начальная настройка сервера Ubuntu 18.04. В системе должен быть задан пользователь без привилегий root с привилегиями sudo, а также должен быть включен брандмауэр.
- Доменное имя, указывающее на публичный IP-адрес вашего сервера. В этом обучающем модуле мы будем использовать доменное имя example.com.
- Веб-сервер Nginx, установленный в соответствии с указаниями обучающего модуля Установка Nginx в Ubuntu 18.04.
- Конфигурация Nginx с SSL с использованием сертификатом Let’s Encrypt. Защита веб-сервера Nginx сертификатом Let’s Encrypt в Ubuntu 18.04 поможет вам выполнить необходимые настройки.
Если предварительные требования выполнены, у вас должен быть сервер, обслуживающий используемую по умолчанию страницу назначения вашего домена по адресу https:// example.com / .
Шаг 1 — Установка Node.js
Для начала мы установим самый быстрый выпуск LTS Node.js, используя архивы пакетов NodeSource.
Вначале мы установим NodeSource PPA, чтобы получить доступ к его содержимому. Перейдите в каталог home и используйте curl для получения скрипта установки архивов Node.js 8.x:
Вы можете просмотреть содержимое скрипта с помощью nano или предпочитаемого текстового редактора:
Завершив проверку скрипта, запустите его от имени пользователя sudo :
Архив PPA будет добавлен в вашу конфигурацию и кэш локальных пакетов автоматически обновится. После запуска скрипта установки Nodesource вы можете установить пакет Node.js:
Чтобы проверить номер версии Node.js, установленной на начальном шаге, введите:
Outputv8.11.3
Примечание. При установке из NodeSource PPA исполняемый файл Node.js имеет имя nodejs , а не node .
Пакет nodejs содержит двоичный файл nodejs , а также диспетчер пакетов npm для модулей Node, так что отдельно устанавливать npm не нужно.
npm использует файл конфигурации в домашнем каталоге, чтобы отслеживать обновления. Он создается при первом запуске npm . Выполните следующую команду, чтобы проверить установку npm и создать файл конфигурации:
Output5.6.0
Для работы некоторых пакетов npm (например, требующих компиляцию кода из источника) потребуется установить пакет build-essential :
Теперь у вас есть необходимые инструменты для работы с пакетами npm , которые требуют компиляции кода из источника.
Установив исполняемый модуль Node.js, мы можем перейти к написанию приложения Node.js.
Шаг 2 — Создание приложения Node.js
Напишем приложение Hello World, возвращающее «Hello World» в ответ на любые запросы HTTP. Этот образец приложения поможет вам выполнить настройку Node.js. Вы можете заменить его собственным приложением, но при этом обязательно измените приложение для прослушивания подходящих IP-адресов и портов.
Вначале создадим образец приложения под именем hello.js :
Вставьте в файл следующий код:
const http = require('http'); const hostname = 'localhost'; const port = 3000; const server = http.createServer((req, res) => res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World!\n'); >); server.listen(port, hostname, () => console.log(`Server running at http://$hostname>:$port>/`); >);
Сохраните файл и выйдите из редактора.
Это приложение Node.js прослушивает заданный адрес ( localhost ) и порт ( 3000 ) и возвращает текст «Hello World!» с кодом успешного выполнения a 200 HTTP. Поскольку мы прослушиваем localhost , удаленные клиенты не смогут подключиться к нашему приложению.
Чтобы протестировать приложение, введите:
Результат будет выглядеть следующим образом:
OutputServer running at http://localhost:3000/
Примечание. Такой способ запуска приложения Node.js блокирует дополнительные команды, пока приложение не будет закрыто нажатием CTRL+C .
Чтобы протестировать приложение, откройте на сервере другой сеанс терминала и подключитесь к localhost с помощью команды curl :
Если вы увидите следующий результат, приложение работает нормально и прослушивает правильные адрес и порт:
OutputHello World!
Если вы не видите ожидаемого результата, убедитесь, что ваше приложение Node.js запущено и настроено для прослушивание правильных адреса и порта.
Убедившись, что приложение работает, остановите его (если еще не сделали этого) нажатием CTRL+C .
Шаг 3 — Установка PM2
Теперь установим диспетчер процессов PM2, предназначенный для приложений Node.js. PM2 позволяет преобразовывать приложения в демонов, чтобы они работали как службы в фоновом режиме.
Используйте npm для установки последней версии PM2 на своем сервере:
Опция -g указывает npm выполнить глобальную установку модуля, чтобы он был доступен в масштабе всей системы.
Вначале используем команду pm2 для запуска вашего приложения hello.js в фоновом режиме:
Также она добавит ваше приложение в список процессов PM2, которы йвыводится при каждом запуске приложения:
Output[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /home/sammy/hello.js in fork_mode (1 instance) [PM2] Done. ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬───────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │ ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤ │ hello │ 0 │ fork │ 1338 │ online │ 0 │ 0s │ 0% │ 23.0 MB │ sammy │ disabled │ └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘ Use `pm2 show ` to get more details about an app
Как видите, PM2 автоматически назначает App name (по имени файла, без расширения .js и идентификатор PM2 id . PM2 также обслуживает и другие данные, в том числе PID процесса, данные о текущем состоянии и использовании памяти.
Приложения, запускаемые через PM2, автоматически перезапускаются в случае сбоя или прекращения работы приложения, но мы можем выполнить дополнительный шаг, чтобы запускать приложение при запуске системы с помощью субкоманды startup . Эта субкоманда генерирует и настраивает скрипт запуска PM2 и управляемых им процессов при загрузке сервера:
Последняя строка результатов содержит команду, которую нужно запустить с привилегиями суперпользователя для настройки запуска PM2 при загрузке:
Output[PM2] Init System found: systemd [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Запустите команду из результатов, указав свое имя пользователя вместо sammy :
Дополнительно мы можем сохранить список процессов PM2 и соответствующие среды:
Теперь вы создали блок systemd, который запускает pm2 для вашего пользователя при загрузке. Этот экземпляр pm2 запускает hello.js .
Запустите службу с помощью команды systemctl :
Проверьте состояние блока systemd:
В дополнение к уже описанным субкомандам PM2 предоставляет много субкоманд, позволяющих управлять информацией о ваших приложениях и искать такую информацию.
Остановите приложение с помощью этой команды (укажите имя приложения PM2 или id ):
Выведем список приложений, управление которыми осуществляет PM2:
Получим информацию об определенном приложении по App name :
Монитор процесса PM2 запускается с помощью субкоманды monit . При этом отображается состояние приложение, использование ресурсов ЦП и использование памяти:
При запуске команды pm2 без аргументов отображается страница справки с примерами использования.
Теперь ваше приложение Node.js запущено и управляется PM2, и мы можем настроить обратный прокси-сервер.
Шаг 4 — Настройка Nginx в качестве обратного прокси-сервера
Ваше приложение запущено и прослушивает localhost , но вам нужно дать пользователям возможность доступа к нему. Для этой цели мы настроим веб-сервер Nginx в качестве обратного прокси-сервера.
В предварительных обучающих модулях вы настроили конфигурацию Nginx в файле /etc/nginx/sites-available/ example.com . Откройте этот файл для редактирования:
В блоке server должен содержаться блок location / . Замените содержимое этого блока следующей конфигурацией. Если ваше приложение настроено для прослушивания другого порта, измените номер порта в выделенной части на подходящий:
/etc/nginx/sites-available/example.com
server < . location / < proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; > . >
Так сервер настраивается для ответа на запросы root. Если наш сервер доступен по адресу example.com , при попытке доступа к https:// example.com / через браузер будет отправлен запрос hello.js с прослушиванием порта 3000 хоста localhost .
Вы можете добавить в этот же серверный блок дополнительные блоки location , чтобы предоставить другим приложениям доступ к этому же серверу. Например, если вы используете другое приложение Node.js на порту 3001 , вы сможете добавить следующий блок location, чтобы разрешить доступ к нему через https:// example.com / app2 :
/etc/nginx/sites-available/example.com — Optional
server < . location /app2 < proxy_pass http://localhost:3001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; > . >
Завершив добавление блоков location для ваших приложений, сохраните файл и закройте редактор.
Убедитесь в отсутствии ошибок синтаксиса с помощью следующей команды:
Если ваше приложение Node.js запущено и конфигурации вашего приложения и Nginx настроены правильно, вы должны иметь возможность доступа к вашему приложению через обратный прокси-сервер Nginx. Попробуйте открыть URL вашего сервера (публичный IP-адрес или доменное имя).
Заключение
Поздравляем! Теперь у вас есть приложение Node.js, работающее за обратным прокси-сервером Nginx на сервере Ubuntu 18.04. Настройка обратного прокси-сервера достаточно гибкая, чтобы предоставить вашим пользователям доступ к другим приложениям или статическому веб-контенту, который вы хотите опубликовать.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Установка Node.js в Ubuntu 20.04

Node.js — это среда выполнения JavaScript для программирования на стороне сервера. Она позволяет разработчикам создавать масштабируемый серверный функционал с помощью JavaScript, языка, который многим уже знаком по веб-разработке под браузер.
В этом обучающем модуле мы покажем вам три разных варианта установки Node.js на сервере Ubuntu 20.04:
- использование apt для установки пакета nodejs из репозитория ПО Ubuntu по умолчанию
- использование apt с альтернативным репозиторием ПО PPA для установки определенных версий пакета nodejs
- установка диспетчера nvm (Node Version Manager) и его использование для установки нескольких версий node и управления ими
Для многих пользователей будет достаточно использовать apt с репозиторием по умолчанию. Если вам требуется определенная более новая (или старая) версия Node, вам следует использовать репозиторий PPA. Если вы занимаетесь активной разработкой приложений Node, и вам нужно часто переключаться между версиями node , используйте метод nvm .
Предварительные требования
Для целей этого обучающего модуля предполагается, что вы используете ОС Ubuntu 20.04. Для начала вам потребуется учетная запись пользователя без привилегий root с привилегиями sudo. Чтобы создать такую учетную запись следуйте указаниям обучающего модуля «Начальная настройка сервера Ubuntu 20.04».
Вариант 1 — Установка Node.js с помощью Apt из репозиториев по умолчанию
В репозиториях Ubuntu 20.04 по умолчанию содержится версия Node.js, обеспечивающая согласованную работу в разных системах. На момент составления этого обучающего модуля в репозиториях хранится версия 10.19. Это не самая последняя версия, но она должна быть стабильной и подходить для небольших экспериментов с языком.
Для получения этой версии можно использовать диспетчер пакетов apt . Обновите указатель локальных пакетов с помощью следующей команды:
Выполните установку Node.js:
Проверьте, что установка выполнена успешно, запросив у node номер версии:
Outputv10.19.0
Если пакет из репозитория отвечает вашим потребностям, для начала работы с Node.js ничего больше не потребуется. В большинстве случаев также нужно установить npm , диспетчер пакетов Node.js. Для этого установите пакет npm с помощью apt :
Это позволит вам устанавливать модули и пакеты для использования с Node.js.
Вы успешно установили Node.js и npm , используя apt и репозитории ПО Ubuntu по умолчанию. В следующем разделе мы покажем, как использовать альтернативный репозиторий для установки разных версий Node.js.
Вариант 2 — Установка Node.js с помощью Apt через архив NodeSource PPA
Для установки другой версии Node.js вы можете использовать архив PPA (архив персональных пакетов), обслуживаемый NodeSource. Через PPA можно установить другие версии Node.js, кроме доступных в официальных репозиториях Ubuntu. На момент составления этого обучающего модуля доступны версии Node.js v10, v12, v13 и v14.
Вначале установим PPA для получения доступа к его пакетам. Используйте в домашнем каталоге команду curl для получения скрипта установки предпочитаемой версии. Замените 14.x предпочитаемым номером версии (если он отличается).
Дополнительную информацию о доступных версиях можно найти в документации по NodeSource.
Просмотрите содержимое загруженного скрипта в nano (или другом предпочитаемом текстовом редакторе):
Убедившись в безопасности запуска скрипта, закройте редактор и запустите скрипт с привилегиями sudo :
Архив PPA будет добавлен в вашу конфигурацию, и кэш локальных пакетов автоматически обновится. Теперь вы можете установить пакет Node.js, как описывалось в предыдущем разделе:
Убедитесь в установке новой версии, запустив node с флагом версии -v :
Outputv14.2.0
Пакет NodeSource nodejs содержит двоичный код node и npm , так что не нужно устанавливать npm отдельно.
Вы успешно установили Node.js и npm , используя apt и архив NodeSource PPA. В следующем разделе мы покажем, как использовать диспетчер версий Node Version Manager для установки нескольких версий Node.js и управления ими.
Вариант 3 — Установка Node с помощью Node Version Manager
Еще одним способом установки Node.js, который является достаточно гибким, является использование nvm, или Node Version Manager. Это программное обеспечение позволяет устанавливать и поддерживать несколько разных независимых версий Node.js и связанных с ними пакетов Node.
Чтобы установить NVM на ваш сервер Ubuntu 20.04, откройте страницу проекта на GitHub. Скопируйте команду curl из файла README, отображаемого на главной странице. Она позволит получить самую последнюю версию скрипта установки.
Прежде чем передавать команду в bash , рекомендуется проверить скрипт, чтобы убедиться, что он не делает ничего, с чем вы не согласны. Вы можете сделать это, удалив сегмент | bash в конце команды curl :
-
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh
Проверьте и убедитесь, что вы не возражаете против изменений, которые вносит скрипт. Если вас удовлетворит результат, запустите команду еще раз с добавлением | bash в конце. URL-адрес, который вы используете, будет меняться в зависимости от последней версии NVM, но в настоящий момент скрипт можно загрузить и запустить с помощью следующей команды:
Она устанавливает скрипт nvm для вашей учетной записи. Для его использования необходимо сначала получить ваш файл .bashrc :
Теперь вы можете спросить у NVM, какие версии Node доступны:
Output. . . v12.13.0 (LTS: Erbium) v12.13.1 (LTS: Erbium) v12.14.0 (LTS: Erbium) v12.14.1 (LTS: Erbium) v12.15.0 (LTS: Erbium) v12.16.0 (LTS: Erbium) v12.16.1 (LTS: Erbium) v12.16.2 (LTS: Erbium) v12.16.3 (Latest LTS: Erbium) v13.0.0 v13.0.1 v13.1.0 v13.2.0 v13.3.0 v13.4.0 v13.5.0 v13.6.0 v13.7.0 v13.8.0 v13.9.0 v13.10.0 v13.10.1 v13.11.0 v13.12.0 v13.13.0 v13.14.0 v14.0.0 v14.1.0 v14.2.0
Это очень длинный список! Вы можете установить версию Node, введя любую версию релиза, которую вы видите. Например, для получения версии 13.6.0 воспользуйтесь следующей командой:
Вы можете увидеть установленные вами различные версии с помощью следующей команды:
nvm list
Output-> v13.6.0 default -> v13.6.0 node -> stable (-> v13.6.0) (default) stable -> 13.6 (-> v13.6.0) (default) . . .
Она отображает текущую активную версию на первой строке ( -> v13.6.0 ), за которой следуют псевдонимы и версии, на которые указывают эти псевдонимы.
Примечание. Если у вас также имеется версия Node.js, установленная с помощью apt , здесь вы сможете увидеть системную запись. Вы всегда можете активировать установленную системой версию Node с помощью команды nvm use system .
Также вы увидите псевдонимы для различных релизов Node с длительной поддержкой (LTS):
Output. . . lts/* -> lts/erbium (-> N/A) lts/argon -> v4.9.1 (-> N/A) lts/boron -> v6.17.1 (-> N/A) lts/carbon -> v8.17.0 (-> N/A) lts/dubnium -> v10.20.1 (-> N/A) lts/erbium -> v12.16.3 (-> N/A)
Мы можем установить релиз на основе этих псевдонимов. Например, для установки последней версии с долгосрочной поддержкой, erbium , запустите следующую команду:
OutputDownloading and installing node v12.16.3. . . . Now using node v12.16.3 (npm v6.14.4)
Вы можете переключаться между установленными версиями с помощью nvm use :
nvm use v13.6.0
Now using node v13.6.0 (npm v6.13.4)
Вы можете проверить, что установка выполнена успешно, с помощью того же метода, использованного в других разделах. Введите следующую команду:
Outputv13.6.0
Корректная версия Node установлена на нашем компьютере, как мы и ожидали. Совместимая версия npm также доступна.
Заключение
Существует несколько способов запустить и начать использование Node.js на сервере Ubuntu 20.04. Наиболее подходящий метод из вышеперечисленных определяется в зависимости от обстоятельств. Хотя использование упакованной версии из репозитория Ubuntu — самый простой метод, использование nvm или архива NodeSource PPA дает дополнительную гибкость.
Дополнительную информацию о программировании с помощью Node.js можно найти в нашей серии обучающих материалов «Программирование на Node.js».
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Создание веб-сервера в Node.js с помощью модуля HTTP

При просмотре веб-страницы в браузере мы отправляем запрос на другой компьютер в Интернете, который отправляет в ответ веб-страницу. Компьютер, с которым вы взаимодействуете через Интернет, называется веб-сервером. Веб-сервер получает запросы HTTP от клиентов, в том числе от вашего браузера, и отправляет им ответы HTTP, например страницы HTML или код JSON из API.
Для вывода веб-страницы сервер использует разнообразное программное обеспечение. Программное обеспечение может быть клиентским или серверным. Клиентское программное обеспечение отвечает за вывод контента, например за цвета панели навигации и стили текста. Серверное программное обеспечение отвечает за обмен, обработку и хранение данных. За обработку сетевых запросов вашего браузера и взаимодействие с базами данных в основном отвечает серверный код.
Node.js позволяет разработчикам использовать JavaScript для создания серверного кода, хотя традиционно этот язык использовался в браузере для создания клиентского кода. Объединение клиентского и серверного кода в одной среде разработки упрощает создание веб-серверов, и именно поэтому Node.js стал популярным инструментом для написания серверного кода.
В этом обучающем руководстве мы научимся создавать веб-серверы с помощью модуля http , входящего в состав Node.js. Мы создадим веб-серверы, которые смогут возвращать данные JSON, файлы CSV и веб-страницы HTML.
Предварительные требования
- Убедитесь, что на используемом для разработки компьютере установлен Node.js. Для целей этого обучающего руководства мы используем версию Node.js 10.19.0. Чтобы установить его в macOS или Ubuntu 18.04, следуйте указаниям руководства Установка Node.js и создание локальной среды разработки в macOS или раздела Установка с помощью PPA руководства Установка Node.js в Ubuntu 18.04.
- Платформа Node.js позволяет создавать готовые веб-серверы. Для начала вам следует познакомиться с основами Node.js. Для этого вы можете воспользоваться нашим руководством Написание и запуск первой программы на Node.js.
- Также мы посвятим один из разделов этого обучающего руководства асинхронному программированию. Если вы незнакомы с асинхронным программированием в Node.js или с модулем fs для взаимодействия с файлами, вы можете узнать о них больше из нашей статьи Написание асинхронного кода в Node.js.
Шаг 1 — Создание базового сервера HTTP
Для начала мы создадим сервер, возвращающий пользователю обычный текст. При этом мы рассмотрим главные концепции создания сервера, что даст нам необходимую основу для возврата более сложных форматов данных, таких как JSON.
Прежде всего нам нужно настроить доступную среду программирования для выполнения наших упражнений, а также других заданий в настоящей статье. Создайте в терминале папку с именем first-servers :
Затем откройте эту папку:
Затем создайте файл для кода:
Откройте файл в текстовом редакторе. Мы используем редактор nano , потому что он доступен в терминале:
Для начала мы загрузим модуль http , входящий в стандартную комплектацию установки Node.js. Добавьте следующую строку в hello.js :
first-servers/hello.js
const http = require("http");
Модуль http содержит функцию создания сервера, которую мы более детально рассмотрим позднее. Если вы хотите узнать больше о модулях в Node.js, познакомьтесь с нашей статьей Создание модуля Node.js.
На следующем шаге мы определим две константы, хост и порт, к которым будет привязан наш сервер:
first-servers/hello.js
. const host = 'localhost'; const port = 8000;
Как указывалось ранее, веб-серверы принимают запросы из браузеров и других клиентов. Для взаимодействия с веб-сервером обычно вводится доменное имя, которое сервер DNS преобразует в IP-адрес. IP-адрес — это уникальная числовая последовательность, идентифицирующая компьютер в Интернете. Дополнительную информацию о концепции доменных имен можно узнать из нашей статьи Введение в терминологию, компоненты и концепции DNS.
Значение localhost — это специальный частный адрес, с помощью которого компьютеры ссылаются на себя. Обычно оно эквивалентно внутреннему IP-адресу 127.0.0.1 и доступно только локальному компьютеру, но недоступно Интернету или локальным сетям, к которым подключен компьютер.
Порт — это числовое значение, которое серверы используют как точку доступа или «дверь» к нашему IP-адресу. В нашем примере мы будем использовать для нашего веб-сервера порт 8000 . Порты 8080 и 8000 обычно используются при разработке как порты по умолчанию, и в большинстве случаев разработчики предпочитают использовать именно эти порты для серверов HTTP.
Когда мы привяжем наш сервер к этому хосту и порту, мы сможем подключаться к нашему серверу, открывая адрес http://localhost:8000 в локальном браузере.
Добавим специальную функцию, которую в Node.js мы называем прослушиватель запросов. Эта функция предназначена для обработки входящих запросов HTTP и возврата ответа HTTP. Данная функция должна иметь два аргумента, объект запроса и объект ответа. Объект запроса записывает все данные поступающего запроса HTTP. Объект ответа используется для возвращения серверу ответов HTTP.
Нам нужно, чтобы наш первый сервер возвращал следующее сообщение при попытке доступа к нему: «My first server!» .
Добавим эту функцию:
first-servers/hello.js
. const requestListener = function (req, res) res.writeHead(200); res.end("My first server!"); >;
Названия функций обычно описывают их назначение. Например, если мы создаем функцию прослушивателя запросов для вывода списка книг, мы назовем ее listBooks() . Поскольку мы рассматриваем общий пример, мы используем для него общее имя requestListener .
Все функции прослушивания запросов в Node.js принимают два аргумента, req и res (мы можем присвоить им другие имена, если захотим). Отправляемый пользователем запрос HTTP записывается в объекте Request, который соответствует первому аргументу, req . Отправляемый пользователю ответ HTTP формируется посредством взаимодействия с объектом Response во втором аргументе, res .
Первая строка res.writeHead(200); задает код состояния HTTP для ответа. Коды состояния HTTP показывают, насколько хорошо запрос HTTP обработан сервером. В данном случае код состояния 200 соответствует результату «OK» . Если вы хотите узнать больше о различных кодах HTTP, которые могут возвращать ваши веб-серверы, и о значении этих кодов, начните с нашего руководства Диагностика распространенных кодов ошибок HTTP.
Следующая строка функции, res.end(«My first server!») ; , записывает ответ HTTP на клиент, который его запросил. Эта функция возвращает любые данные, которые должен возвращать сервер. В этом случае будут возвращаться текстовые данные.
Теперь мы можем создать сервер и использовать прослушиватель запросов:
first-servers/hello.js
. const server = http.createServer(requestListener); server.listen(port, host, () => console.log(`Server is running on http://$host>:$port>`); >);
Сохраните код и закройте nano , нажав CTRL+X .
В первой строке мы создали новый объект server с помощью функции createServer() модуля http . Этот сервер принимает запросы HTTP и передает их нашей функции requestListener() .
После создания сервера мы должны привязать его к сетевому адресу. Для этого мы используем метод server.listen() . Он принимает три аргумента: port , host и функцию обратного вызова, срабатывающую, когда сервер начинает прослушивание.
Все эти аргументы необязательные, но всегда лучше прямо указать, какие порт и хост должен использовать веб-сервер. При развертывании веб-серверов в разных средах важно знать порт и хост, чтобы настроить балансировку нагрузки или псевдоним DNS.
Функция обратного вызова регистрирует в нашей консоли сообщение о том, когда сервер начал прослушивать соединения.
Примечание. Хотя requestListener() не использует объект req , он должен быть первым аргументом функции.
Мы создали веб-сервер, написав менее пятнадцати строк кода. Проверим его работу, запустив программу:
Мы увидим в консоли следующее:
OutputServer is running on http://localhost:8000
Обратите внимание, что командная строка исчезает. Это связано с тем, что сервер Node.js — это постоянно работающий процесс. Он закрывается только при обнаружении ошибки, вызывающей сбой и завершение работы, или когда мы останавливаем процесс Node.js, запускающий сервер.
Мы используем отдельное окно терминала для взаимодействия с сервером с помощью cURL, инструмента командной строки для обмена данными с сетью. Введите команду для отправки запроса HTTP GET на запущенный нами сервер:
При нажатии клавиши ENTER на терминале появится следующее:
OutputMy first server!
Мы настроили сервер и получили от него первый ответ.
Теперь давайте подробнее разберемся с тем, что произошло во время тестирования сервера. Мы использовали cURL для отправки запроса GET на сервер с адресом http://localhost:8000 . Наш сервер Node.js прослушивал соединения этого адреса. Сервер передал запрос функции requestListener() . Функция вернула текстовые данные с кодом состояния 200 . Сервер отправил ответ в cURL, и на нашем терминале появилось сообщение.
Прежде чем продолжить, нажмем CTRL+C и закроем запущенный сервер. Это прервет работу сервера и вернет нас в командную строку.
Большинство сайтов и API не используют для ответов формат обычного текста. Страницы HTML и данные JSON —наиболее распространенные форматы ответов. На следующем шаге мы узнаем, как возвращать ответы HTTP в распространенных форматах данных, которые мы встречаем в Интернете.
Шаг 2 — Возврат разных типов контента
Возвращаемый веб-сервером ответ может иметь разные форматы. Мы уже упоминали JSON и HTML, но также существуют и другие текстовые форматы, в том числе XML и CSV. Кроме того, веб-серверы могут возвращать данные и не в текстовом формате, в том числе файлы PDF, архивы zip, аудио- и видеофайлы.
В этой статье мы расскажем о возврате следующих типов данных, помимо обычного текста:
Все эти три типа данных основаны на текстовом формате и очень часто используются для распространения контента в Интернете. Многие инструменты и языки разработки для серверов поддерживают возврат этих типов данных. В контексте Node.js нам необходимы две вещи:
- Задать для заголовка Content-Type в ответах HTTP подходящее значение.
- Убедиться, что res.end() получает данные в правильном формате.
Посмотрим примеры в действии. Код, который мы будем писать в этом и следующих разделах, будет очень похож на уже написанный нами код. Большинство изменений существуют в функции requestListener() . Давайте создадим файлы с этим кодом шаблона, чтобы упростить работу в следующих разделах.
Создайте новый файл с именем html.js . Этот файл будет использоваться позднее для возврата текста HTML в ответе HTTP. Здесь мы введем код шаблона и скопируем его в другие серверы, возвращающие разные типы.
Введите в терминале следующее:
Теперь откройте этот файл в текстовом редакторе:
Скопируем код шаблона. Введите в nano следующее:
first-servers/html.js
const http = require("http"); const host = 'localhost'; const port = 8000; const requestListener = function (req, res) >; const server = http.createServer(requestListener); server.listen(port, host, () => console.log(`Server is running on http://$host>:$port>`); >);
Сохраните файл html.js и закройте его с помощью CTRL+X , а затем вернитесь в терминал.
Теперь скопируем этот файл в два новых файла. Первый файл будет возвращать данные CSV в ответе HTTP:
Второй файл будет возвращать ответ JSON на сервере:
Остальные файлы будут предназначены для последующих упражнений:
Теперь мы готовы продолжить наши упражнения. Начнем с возврата JSON.
Вывод JSON
Нотация объектов JavaScript (JSON) представляет собой текстовый формат обмена данными. Как предполагает его название, данный формат основан на объектах JavaScript, но при этом он не зависит от языка, то есть его может использовать любой язык программирования, способный парсить его синтаксис.
Формат JSON обычно используется API для приема и возврата данных. Его популярность обусловлена меньшим размером, чем у XML и других форматов обмена данными, а также наличием инструментов для парсинга его синтаксиса без излишних усилий. Если вы хотите узнать больше о JSON, вы можете прочитать наше руководство Работа с JSON в JavaScript.
Откройте файл json.js с помощью nano :
Нам нужно вернуть ответ JSON. Изменим функцию requestListener() для возврата соответствующего заголовка для всех ответов JSON посредством изменения выделенных строк:
first-servers/json.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "application/json"); >; .
Метод res.setHeader() добавляет заголовок HTTP к ответу. Заголовки HTTP содержат дополнительную информацию, которая может быть прикреплена к запросу или ответу. Метод res.setHeader() принимает два аргумента: название заголовка и его значение.
Заголовок Content-Type используется для указания формата данных, который также называется типом носителя и отправляется с запросом или ответом. В этом случае Content-Type имеет значение application/json .
Возвратим пользователю контент JSON. Изменим json.js следующим образом:
first-servers/json.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "application/json"); res.writeHead(200); res.end(` `); >; .
Как и ранее, мы сообщаем пользователю об успешном выполнении запроса, возвращая статус 200 . Теперь наш аргумент строки в вызове response.end() содержит корректный код JSON.
Сохраните и закройте json.js , нажав CTRL+X . Запустим сервер с помощью команды node :
Подключимся к серверу в другом терминале, используя cURL:
Нажав ENTER , мы увидим следующий результат:
Output
Нам удалось успешно вывести ответ JSON, как и во многих популярных API для создания приложений. Обязательно закройте работающий сервер, нажав CTRL+C , чтобы вернуться в стандартную командную строку терминала. Теперь перейдем к CSV, другому популярному формату вывода данных.
Обслуживание CSV
Формат разделенных запятой значений (CSV) — это стандартный текстовый формат вывода табличных данных. В большинстве случаев строки разделяются символами новой строки, а элементы внутри строки разделяются запятым.
Откройте файл csv.js в нашем рабочем пространстве с помощью текстового редактора:
Добавим следующие строки в функцию requestListener() :
first-servers/csv.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "text/csv"); res.setHeader("Content-Disposition", "attachment;filename=oceanpals.csv"); >; .
Теперь Content-Type имеет значение text/csv , соответствующее формату файлов CSV. Также мы добавим заголовок Content-Disposition . Этот заголовок указывает браузеру способ отображения данных, особенно в браузере или в отдельном файле.
При возврате ответов CSV большинство современных браузеров автоматически загружают файл, даже если заголовок Content-Disposition не установлен. Однако при возврате файла CSV этот заголовок нужно добавить, поскольку он позволяет нам задать имя файла CSV. Мы сообщаем браузеру, что файл CSV является вложением, и что его следует загрузить. Затем мы сообщаем браузеру, что файлу присвоено имя oceanpals.csv .
Запишем данные CSV в ответе HTTP:
first-servers/csv.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "text/csv"); res.setHeader("Content-Disposition", "attachment;filename=oceanpals.csv"); res.writeHead(200); res.end(`id,name,email\n1,Sammy Shark,shark@ocean.com`); >; .
Как и раньше, мы возвращаем статус 200 / OK в нашем ответе. Теперь наш вызов res.end() содержит строку корректного файла CSV. Значения в каждом столбце разделяются запятыми, а строки разделяются символом новой строки ( \n ). У нас имеется две строки, одна для заголовка таблицы, а другая — для данных.
Протестируем этот сервер в браузере. Сохраните файл csv.js и закройте редактор, нажав CTRL+X .
Запустите сервер с помощью команды Node.js:
Откроем сервер в другом терминале с помощью cURL:
На консоли появится следующее:
Outputid,name,email 1,Sammy Shark,shark@ocean.com
Если мы откроем в браузере адрес http://localhost:8000 , загрузится файл CSV. Файл будет иметь имя oceanpals.csv .
Закройте работающий сервер, нажав CTRL+C для возврата в стандартную командную строку терминала.
Мы рассмотрели возврат данных в форматах JSON и CSV, которые часто используются в API. Теперь перейдем к возврату данных сайтов, просматриваемых людьми в браузере.
Обслуживание кода HTML
Гипертекстовый язык разметки (HTML) — самый распространенный формат, используемый пользователями при взаимодействии с серверами через браузер. Он был создан для структурирования веб-контента. Браузеры разработаны для отображения контента в формате HTML, оформленного с использованием стилей CSS, еще одной клиентской веб-технологии для настройки внешнего вида сайтов.
Откроем файл html.js в текстовом редакторе еще раз:
Изменим функцию requestListener() так, чтобы она возвращала подходящий заголовок Content-Type для ответа HTML:
first-servers/html.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "text/html"); >; .
Возвратим пользователю контент HTML. Добавьте в файл html.js выделенные строки, чтобы он выглядел следующим образом:
first-servers/html.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "text/html"); res.writeHead(200); res.end(`This is HTML
`); >; .
Вначале мы добавляем код состояния HTTP. Затем мы вызываем response.end() с аргументом строки, содержащим корректный код HTML. Открывая сервер в браузере, мы увидим страницу HTML с одним тегом заголовка со значением This is HTML .
Сохраним файл и закроем редактор, нажав CTRL+X . Запустим сервер с помощью команды node :
После запуска программы мы увидим сообщение Server is running on http://localhost:8000 .
Откройте в браузере адрес http://localhost:8000 . Страница будет выглядеть следующим образом:

Закроем работающий сервер, нажав CTRL+C для возврата в стандартную командную строку терминала.
Код HTML часто добавляется в файл отдельно от серверного кода, такого как наши программы Node.js. Посмотрим, как можно выводить ответы HTML из файлов.
Шаг 3 — Вывод страницы HTML из файла
Код HTML можно выводить пользователю в виде строк Node.js, но желательно загружать файлы HTML и выводить их содержимое. Так нам не нужно хранить длинные строки кода HTML в файле Node.js, за счет чего код становится более компактным, и мы получаем возможность независимо работать с разными частями сайта. Такая концепция разделения часто используется в веб-разработке, поэтому важно знать, как правильно загружать файлы HTML для их поддержки в Node.js.
Для вывода файлов HTML мы загружаем их с помощью модуля fs и используем их данные при написании ответа HTTP.
Вначале создадим файл HTML, который будет возвращать наш веб-сервер. Создайте новый файл HTML:
Откройте файл index.html в текстовом редакторе:
Наша веб-страница будет минимальной. Она будет иметь оранжевый фон и содержать текст приветствия в центре. Добавьте в файл следующий код:
first-servers/index.html
DOCTYPE html> head> title>My Websitetitle> style> *, html margin: 0; padding: 0; border: 0; > html width: 100%; height: 100%; > body width: 100%; height: 100%; position: relative; background-color: rgb(236, 152, 42); > .center width: 100%; height: 50%; margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-family: "Trebuchet MS", Helvetica, sans-serif; text-align: center; > h1 font-size: 144px; > p font-size: 64px; > style> head> body> div class="center"> h1>Hello Again!h1> p>This is served from a filep> div> body> html>
На этой веб-странице отображается две строки текста: Hello Again! и This is served from a file . Строки отображаются друг над другом в центре страницы. Первая строка текста отображается как заголовок, то есть она будет больше. Вторая строка текста будет немного меньше. Весь текст будет выводиться белым цветом на оранжевом фоне страницы.
Хотя это не относится к настоящей статье и серии статей, вы можете узнать больше об HTML, CSS и других технологиях создания веб-клиентов с помощью руководства Введение в веб-технологии от Mozilla.
Это весь код HTML, который нам нужен, так что теперь можно сохранить и закрыть файл, нажав CTRL+X . Теперь мы можем перейти к коду сервера.
В этом упражнении мы будем работать с файлом htmlFile.js . Откройте этот файл в текстовом редакторе:
Поскольку нам нужно прочитать файл, для начала импортируем модуль fs :
first-servers/htmlFile.js
const http = require("http"); const fs = require('fs').promises; .
Этот модуль содержит функцию readFile() , которую мы будем использовать для загрузки файла HTML. Мы импортируем вариант обещания в соответствии с современными передовыми практиками работы с JavaScript. Мы используем обещания, поскольку с синтаксической точки зрения они лучше функций обратного вызова, к которым нам пришлось бы прибегнуть, если бы мы назначили fs как require(‘fs’) . Дополнительную информацию о лучших практиках асинхронного программирования можно найти в нашем руководстве Написание асинхронного кода в Node.js.
Нам нужно, чтобы при отправке пользователем запроса к системе считывался наш файл HTML. Для начала изменим requestListener() для чтения файла:
first-servers/htmlFile.js
. const requestListener = function (req, res) fs.readFile(__dirname + "/index.html") >; .
Мы используем метод fs.readFile() для загрузки файла. Он использует аргумент __dirname + «/index.html» . Специальная переменная __dirname содержит абсолютный путь к директории запуска кода Node.js. В конце мы добавляем /index.html , чтобы мы могли загрузить ранее созданный файл HTML.
Возвратим страницу HTML после ее загрузки:
first-servers/htmlFile.js
. const requestListener = function (req, res) fs.readFile(__dirname + "/index.html") .then(contents => res.setHeader("Content-Type", "text/html"); res.writeHead(200); res.end(contents); >) >; .
Если обещание fs.readFile() успешно выполняется, оно возвращает свои данные. Для этого случая мы используем метод then() . Параметр contents содержит данные файла HTML.
Вначале мы задаем для заголовка Content-Type значение text/html , чтобы сообщить клиенту, что мы возвращаем данные HTML. Затем мы пишем код состояния, показывая, что запрос выполнен успешно. В заключение мы отправляем на клиент загруженную страницу HTML с данными в переменной contents .
Иногда метод fs.readFile() может выполняться с ошибками, и нам нужно предусмотреть подобные случаи. Добавьте в функцию requestListener() следующее:
first-servers/htmlFile.js
. const requestListener = function (req, res) fs.readFile(__dirname + "/index.html") .then(contents => res.setHeader("Content-Type", "text/html"); res.writeHead(200); res.end(contents); >) .catch(err => res.writeHead(500); res.end(err); return; >); >; .
Сохраните файл и закройте nano , нажав CTRL+X .
Когда в обещании возникает ошибка, оно отклоняется. Эта ситуация обрабатывается с помощью метода catch() . Он принимает ошибку, возвращаемую fs.readFile() , устанавливает код состояния 500 , сигнализирующий о внутренней ошибке, и возвращает пользователю сообщение об ошибке.
Запустите наш сервер с помощью команды node :
Откройте в браузере адрес http://localhost:8000 . Вы увидите следующую страницу:

Мы вывели пользователю страницу HTML с сервера. Теперь мы можем закрыть запущенный сервер, нажав CTRL+C . Сделав это, мы увидим командную строку терминала.
При написании такого кода в производственной среде не всегда желательно загружать страницу HTML при каждом получении запроса HTTP. В нашем случае страница HTML занимает всего 800 байт, но на сложных сайтах размер страниц может доходить до нескольких мегабайт. Загрузка больших файлов занимает много времени. Если на вашем сайте ожидается большой трафик, лучше всего загружать файлы HTML при запуске и сохранять их содержимое. После их загрузки вы можете настроить сервер так, чтобы он прослушивал запросы адреса.
Чтобы продемонстрировать этот метод, покажем, как можно сделать сервер более эффективным и масштабируемым.
Эффективный вывод кода HTML
Вместо того чтобы загружать страницу HTML для каждого запроса, мы загрузим ее только один раз, в самом начале. Запрос будет возвращать данные, загруженные нами при запуске.
Откройте в терминале скрипт Node.js с помощью текстового редактора:
Добавим новую переменную, прежде чем создавать функцию requestListener() :
first-servers/htmlFile.js
. let indexFile; const requestListener = function (req, res) .
При запуске программы эта переменная будет хранить содержимое файла HTML.
Изменим функцию requestListener() . Теперь вместо загрузки файла она будет возвращать содержимое indexFile :
first-servers/htmlFile.js
. const requestListener = function (req, res) res.setHeader("Content-Type", "text/html"); res.writeHead(200); res.end(indexFile); >; .
Далее мы изменим логику чтения файла с функции requestListener() на момент запуска нашего сервера. Внесите следующие изменения при создании сервера:
first-servers/htmlFile.js
. const server = http.createServer(requestListener); fs.readFile(__dirname + "/index.html") .then(contents => indexFile = contents; server.listen(port, host, () => console.log(`Server is running on http://$host>:$port>`); >); >) .catch(err => console.error(`Could not read index.html file: $err>`); process.exit(1); >);
Сохраните файл и закройте nano , нажав CTRL+X .
Код, считывающий файл, похож на написанный нами при первой попытке. Однако при успешном чтении файла мы можем сохранить его содержимое в глобальной переменной indexFile . Мы запустим сервер с методом listen() . Главное — загрузить файл до запуска сервера. Так функция requestListener() гарантированно возвращает страницу HTML, поскольку переменная indexFile больше не пустая.
Блок обработки ошибок также изменился. Если файл не удается загрузить, мы записываем ошибку и выводим ее на консоль. Затем мы закрываем программу Node.js с помощью функции exit() без запуска сервера. Так мы видим, почему не удалось прочитать файл, и можем решить проблему и снова запустить сервер.
Мы создали разные веб-серверы, возвращающие пользователю разные типы данных. Пока что мы не использовали данные запросов для определения конкретного возвращаемого контента. Нам потребуется использовать данные запросов при настройке маршрутов или путей сервера Node.js, так что теперь мы посмотрим, как это работает.
Шаг 4 — Управление маршрутами с использованием объекта HTTP Request
Большинство посещаемых нами сайтов и используемых нами API имеют несколько конечных точек, что позволяет получать доступ к разным ресурсам. Хорошим примером является система управления книгами, которая может использоваться в библиотеке. Ей нужно будет не только управлять данными книг, но и управлять данными авторов для составления каталогов и обеспечения удобства поиска.
Хотя данные книг и авторов связаны, они представляют собой разные объекты. В подобных случаях разработчики обычно программируют каждый объект для разных конечных точек, чтобы показать пользователю API, с какими данными он взаимодействует.
Создадим новый сервер для небольшой библиотеки, который будет возвращать два разных типа данных. Если пользователь откроет адрес сервера с /books , он получит список книг в формате JSON. Если пользователь откроет раздел /authors , он получит список с информацией об авторах в формате JSON.
До сих пор мы возвращали одинаковые ответы на каждый получаемый запрос. Рассмотрим небольшой пример.
Запустим заново наш пример с ответом JSON:
Отправим на другом терминале запрос cURL, как мы делали ранее:
Вы увидите следующее:
Output
Node.JS для решения задач
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
В этом разделе предлагаются задачи по теме AJAX.
Конечно же, они требуют взаимодействия с сервером. Мы будем использовать серверную часть, написанную на JavaScript, на Node.JS.
Если вы не использовали Node.JS ранее – не беспокойтесь. Здесь нашей целью является преимущественно клиентская часть, поэтому прямо сейчас изучать Node.JS не обязательно. Серверные скрипты уже готовы. Нужно только поставить Node.JS и модули, чтобы их запускать.
Установка
Для настройки окружения будет достаточно сделать два шага:
- Сначала установите сам сервер Node.JS. Если у вас Unix-система – рекомендуется собрать последнюю версию из исходников, а также NPM. Вы справитесь. Если Windows – посетите сайт https://nodejs.org или скачайте установщик (32 или 64-битный) с расширением .msi из https://nodejs.org/dist/latest/.
- Выберите директорию, в которой будете решать задачи. Запустите в ней:
npm install node-static
Проверка
-
Создайте какую-нибудь поддиректорию и в ней файл server.js с таким содержимым:
var http = require('http'); var static = require('node-static'); var file = new static.Server('.'); http.createServer(function(req, res) < file.serve(req, res); >).listen(8080); console.log('Server running on port 8080');
Server running on port 8080
Нельзя запустить больше одного сервера одновременно!
При попытке запуска двух серверов (например, в разных консолях) – будет конфликт портов и ошибка.
- Откройте в браузере http://127.0.0.1:8080/server.js. Должно вывести код файла server.js .
Если всё работает – отлично, теперь вы готовы решать задачи.
Примеры
В примерах, за редким исключением, для краткости будет приводиться не полный скрипт на Node.JS, а только код обработки запроса.
var http = require('http'); var url = require('url'); var querystring = require('querystring'); function accept(req, res) < res.writeHead(200, < 'Content-Type': 'text/plain', 'Cache-Control': 'no-cache' >); res.end("OK"); > http.createServer(accept).listen(8080);
…Будет только функция accept , или даже только её содержимое:
res.writeHead(200, < 'Content-Type': 'text/plain', 'Cache-Control': 'no-cache' >);
Основные методы
В функции accept используются два объекта:
- req – объект запроса («request»), то есть то, что прислал клиент (обычно браузер), из него читаем данные.
- res – объект ответа («response»), в него пишем данные в ответ клиенту.
- вызов res.writeHead(HTTP-код, [строка статуса], ) пишет заголовки.
- вызов res.write(txt) пишет текст в ответ.
- вызов res.end(txt) – завершает запрос ответом.
Демо
Кроме просмотра кода, можно будет попробовать и скачать различные демки.
Вот пример демо, можете попробовать нажать на кнопку – она работает.
Если хотите посмотреть пример поближе и поиграть с ним – скачайте архив (кнопка справа-сверху в примере выше), он будет работать и на вашем Node.JS.
Больше о Node.JS
Больше о сервере Node.JS можно узнать в скринкасте по Node.JS.