Как написать сервер на JavaScript

Как написать сервер на javascript

Как написать сервер на javascript

Write

Выбор среды выполнения Node.js и установка

Выбор среды выполнения Node.js и установка

Node.js распространяется в двух основных вариантах: LTS (Long-Term Support) и Current. Для серверных приложений рекомендуется LTS-ветка, так как она получает обновления безопасности и поддержку дольше. Версия Current подходит для тестирования новых возможностей, но не гарантирует долгосрочной стабильности.

Проверить актуальные версии можно на официальном сайте nodejs.org.

  • LTS: обновляется раз в 2 года, поддерживается около 30 месяцев.
  • Current: выпускается чаще, но быстро устаревает.

Установка:

  1. Скачайте установочный пакет с nodejs.org под вашу ОС.
  2. Для Linux удобнее использовать менеджер версий nvm:
    • Установите nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
    • Проверьте: command -v nvm
    • Установите Node.js LTS: nvm install --lts
  3. Для macOS установка также возможна через Homebrew: brew install node.
  4. Для Windows используйте MSI-пакет с официального сайта или пакетный менеджер choco install nodejs-lts.

Проверка после установки:

  • node -v – версия Node.js
  • npm -v – версия менеджера пакетов

Создание минимального HTTP-сервера с использованием встроенного модуля

Создание минимального HTTP-сервера с использованием встроенного модуля

Для запуска простого сервера достаточно встроенного модуля http. Он позволяет принимать запросы и отправлять ответы без дополнительных библиотек.

Пример кода:

const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Сервер работает');
});
server.listen(3000, '127.0.0.1', () => {
console.log('Сервер запущен на http://127.0.0.1:3000/');
});

createServer принимает функцию-обработчик с аргументами req и res. Метод writeHead задаёт код ответа и заголовки, а end завершает отправку данных.

Для локальной отладки достаточно вызвать сервер командой node файл.js. После запуска можно открыть указанный адрес в браузере и проверить ответ.

Обработка маршрутов и разных типов запросов

Обработка маршрутов и разных типов запросов

Для организации маршрутов в Node.js часто применяют модуль http или библиотеку express. В чистом Node.js обработка строится на анализе req.url и req.method, а в Express маршруты описываются компактнее.

Пример обработки в Express:

const express = require('express');
const app = express();
app.get('/users', (req, res) => {
res.send('Список пользователей');
});
app.post('/users', (req, res) => {
res.send('Создание пользователя');
});
app.put('/users/:id', (req, res) => {
res.send(`Обновление пользователя ${req.params.id}`);
});
app.delete('/users/:id', (req, res) => {
res.send(`Удаление пользователя ${req.params.id}`);
});
app.listen(3000);

В таблице приведены базовые HTTP-методы и их назначение:

Метод Назначение Пример маршрута
GET Получение данных /articles
POST Создание ресурса /articles
PUT Полное обновление /articles/5
PATCH Частичное обновление /articles/5
DELETE Удаление ресурса /articles/5

Для сложных приложений рекомендуется группировать маршруты в отдельные модули и подключать их через app.use(), что облегчает поддержку и тестирование.

Передача и получение данных в формате JSON

Передача и получение данных в формате JSON

Для работы с JSON на сервере JavaScript удобно использовать встроенный метод JSON.parse() для преобразования входящих строк в объект и JSON.stringify() для подготовки ответа.

Пример обработки запроса с JSON в Node.js:

const http = require('http');
const server = http.createServer((req, res) => {
if (req.method === 'POST' && req.headers['content-type'] === 'application/json') {
let body = '';
req.on('data', chunk => { body += chunk; });
req.on('end', () => {
const data = JSON.parse(body);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ received: data }));
});
} else {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Ожидается JSON');
}
});
server.listen(3000);

Для корректного обмена данными необходимо всегда указывать заголовок Content-Type: application/json как в запросе, так и в ответе. Это гарантирует, что клиент и сервер одинаково интерпретируют содержимое.

При обработке больших JSON полезно ограничивать размер входящего тела запроса во избежание перегрузки памяти. Это можно реализовать через проверку длины строки при накоплении данных.

Работа с файлами и отдача статического контента

Работа с файлами и отдача статического контента

Для чтения и записи файлов используйте модуль fs. Асинхронные методы fs.readFile и fs.writeFile позволяют не блокировать поток событий. Для больших файлов применяйте fs.createReadStream и fs.createWriteStream с методом pipe, чтобы снизить нагрузку на память.

Отдавая статический контент, формируйте полный путь через path.join(__dirname, 'public', req.url). Проверяйте существование файла с помощью fs.access или fs.existsSync, чтобы вернуть корректный код ответа.

Заголовки Content-Type должны соответствовать типу файла: text/html для HTML, text/css для CSS, application/javascript для JS, image/png или image/jpeg для изображений. Для кэширования используйте Cache-Control: public, max-age=3600 и ETag через fs.stat.

Для ускорения повторных запросов храните часто запрашиваемые файлы в буфере памяти и проверяйте обновления через mtime. Для бинарных файлов устанавливайте Content-Length и используйте потоковую передачу для минимизации задержек.

Для безопасности исключайте из req.url последовательности вроде ../, чтобы предотвратить доступ к файлам за пределами публичной директории.

Использование фреймворка Express для упрощения кода

Использование фреймворка Express для упрощения кода

Express – минималистичный фреймворк для Node.js, позволяющий создавать веб-серверы с минимальными усилиями. Он снимает необходимость ручного управления низкоуровневыми аспектами HTTP, такими как маршрутизация, обработка запросов и формирование ответов.

Для начала работы необходимо установить Express через npm:

npm install express

Создание базового сервера сводится к нескольким строкам кода:

const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Сервер работает');
});
app.listen(port, () => {
console.log(Сервер запущен на порту ${port});
});

Express упрощает следующие задачи:

  • Маршрутизация: поддержка динамических и параметризованных URL через app.get, app.post, app.put, app.delete.
  • Обработка данных запроса: встроенный парсер JSON и URL-кодированных форм через express.json() и express.urlencoded().
  • Подключение промежуточного ПО (middleware): логирование, аутентификация, обработка ошибок.
  • Статические файлы: простая публикация директорий с помощью app.use(express.static('public')).

Рекомендации для организации кода с Express:

  1. Разделять маршруты по отдельным файлам, импортируя их через require и app.use.
  2. Использовать middleware только по необходимости, чтобы избежать ненужной нагрузки на сервер.
  3. Сразу обрабатывать ошибки через централизованное middleware с четырьмя параметрами: (err, req, res, next).
  4. Писать тесты для ключевых маршрутов, так как Express не скрывает логику работы с запросами.

Использование Express снижает количество повторяющегося кода, делает структуру приложения прозрачной и ускоряет разработку серверной части. В проектах средней и большой сложности применение этого фреймворка значительно упрощает поддержку и масштабирование.

Запуск сервера на порту и проверка через браузер или Postman

Создайте файл server.js и подключите модуль http: const http = require('http');

Определите порт для прослушивания, например 3000: const PORT = 3000;

Создайте сервер с обработкой запросов: const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Сервер работает'); });

Запустите сервер: server.listen(PORT, () => { console.log(`Сервер запущен на порту ${PORT}`); });

В браузере откройте http://localhost:3000. Должен отобразиться текст Сервер работает.

Для проверки в Postman создайте GET-запрос на http://localhost:3000. Ответ должен иметь статус 200 OK и тело Сервер работает. Заголовок Content-Typetext/plain.

Если порт занят, Node.js выдаст ошибку. На Linux/macOS используйте lsof -i :3000 и kill -9 PID, на Windows – завершите процесс через Task Manager.

Для фонового запуска сервера применяйте pm2 start server.js или forever start server.js для автоматического перезапуска при сбое.

Вопрос-ответ:

Какой модуль лучше использовать для создания простого HTTP-сервера на JavaScript?

Для базового HTTP-сервера в JavaScript обычно используют встроенный модуль http. Он позволяет создать сервер без установки дополнительных библиотек. Вы создаёте сервер через http.createServer(), указываете функцию для обработки запросов и запускаете его на выбранном порту методом listen(). Такой подход удобен для небольших проектов и тестирования.

Можно ли обрабатывать маршруты без сторонних библиотек?

Да, можно. Внутри функции обработки запросов сервера вы получаете объект запроса, где есть поле url. По его значению можно сравнивать путь и вызывать разные функции для каждого маршрута. Например, if (req.url === '/about') — это позволит отобразить отдельную страницу. Этот метод подходит для простых серверов, но при большом количестве маршрутов код становится сложным.

Как обрабатывать данные, которые приходят через POST-запрос?

Для обработки POST-запросов нужно слушать событие 'data' объекта запроса и постепенно собирать данные в буфер. После окончания передачи срабатывает событие 'end', где можно объединить все части и преобразовать их, например, в строку или JSON. Такой способ работает с любыми типами данных, но требует внимательного контроля ошибок и ограничения размера получаемой информации.

Стоит ли использовать асинхронные функции при работе с файлами на сервере?

Да, асинхронные функции помогают не блокировать основной поток при работе с файловой системой. Например, методы fs.readFile() или fs.writeFile() имеют асинхронные версии. Если использовать их синхронные аналоги, сервер может перестать отвечать на другие запросы до завершения операции с файлом. Асинхронный подход улучшает отзывчивость и позволяет обрабатывать несколько запросов одновременно.

Как отлаживать сервер на Node.js, если он не запускается?

Сначала проверяют, свободен ли порт, который вы указываете в listen(). Затем стоит проверить наличие синтаксических ошибок и корректность импортов модулей. Полезно использовать console.log() на каждом этапе — при старте сервера и при обработке запроса. Можно запускать сервер с ключом --inspect и подключать отладчик, чтобы пошагово отслеживать выполнение кода.

Как выбрать между использованием Node.js и других технологий для написания сервера на JavaScript?

Node.js предоставляет возможность запускать JavaScript на сервере, что удобно, если вы уже знакомы с языком на клиентской стороне. Он хорошо подходит для обработки большого числа одновременных соединений благодаря своей неблокирующей модели ввода-вывода. Если задачи сервера связаны с интенсивными вычислениями, можно рассмотреть дополнительные инструменты, например, использование потоков или специализированные серверные платформы на других языках, которые лучше справляются с тяжёлыми вычислительными нагрузками. Важно учитывать как опыт команды, так и требования проекта: для небольших веб-приложений Node.js может быть самым простым и быстрым вариантом, а для высоконагруженных систем иногда выбирают другие решения.

Ссылка на основную публикацию