1. Что такое модуль http и зачем он нужен
Node.js из коробки даёт нам стандартный модуль http, который позволяет создавать собственные HTTP-серверы. Это фундамент для любого веб-приложения на Node.js — будь то сайт, REST API или чат-бот. Без этого модуля Node.js был бы просто "очередной скриптовой средой", а не платформой для серверной разработки.
HTTP (HyperText Transfer Protocol) — это тот самый протокол, по которому браузеры общаются с серверами. Если вы когда-нибудь писали в адресной строке http://example.com, поздравляю: вы уже пользовались HTTP!
Модуль http позволяет:
- Принимать входящие запросы от клиентов (например, браузеров)
- Отправлять ответы клиенту
- Читать содержимое запросов (URL, заголовки, тело)
- Управлять статусами и заголовками ответов
В отличие от браузера, который только отправляет запросы, Node.js может быть "той самой стороной", что слушает и отвечает — то есть сервером.
Как подключить модуль http
Модуль http — это встроенный модуль Node.js, его не нужно устанавливать через npm. Просто подключаем с помощью require (или import, если используете ESM).
const http = require('http'); // CommonJS-стиль
или, если у вас проект на ESM:
import http from 'http';
В этой лекции будем использовать CommonJS — он пока встречается чаще.
2. Первый сервер на Node.js: Hello, HTTP!
Давайте создадим самый простой сервер, который слушает порт и отвечает на все запросы одинаково.
const http = require('http');
// Создаём сервер
const server = http.createServer((req, res) => {
// req — объект запроса, res — объект ответа
res.writeHead(200, { 'Content-Type': 'text/plain' }); // Устанавливаем статус и заголовок
res.end('Hello, world!'); // Отправляем ответ и завершаем соединение
});
// Запускаем сервер на порту 3000
server.listen(3000, () => {
console.log('Сервер запущен на http://localhost:3000');
});
Что здесь происходит:
- Мы создаём сервер функцией http.createServer(), передавая колбэк, который будет вызван на каждый входящий HTTP-запрос.
- Колбэк получает два объекта: req (request, запрос) и res (response, ответ).
- Мы отправляем статус 200 (ОК) и заголовок 'Content-Type: text/plain'.
- Завершаем ответ методом res.end(), отправляя текст "Hello, world!".
- Сервер начинает слушать порт 3000. Если вы откроете браузер и перейдёте по адресу http://localhost:3000 — увидите наше приветствие.
Как это работает: жизненный цикл запроса
Когда кто-то (например, браузер) обращается к вашему серверу (http://localhost:3000), Node.js:
- Получает запрос (например, "GET / HTTP/1.1").
- Создаёт объекты req и res.
- Вызывает вашу функцию-обработчик, передавая эти объекты.
- Ждёт, когда вы отправите ответ с помощью методов объекта res (writeHead, write, end).
- После вызова res.end() соединение закрывается.
Всё просто: сервер — это такой "вечный слушатель", который ждёт запросов и отвечает на них.
3. Разбираем объекты req и res
Объект запроса (req)
Объект req (request) содержит всю информацию о входящем запросе:
- req.method — HTTP-метод (GET, POST, PUT, DELETE и т.д.)
- req.url — путь запроса (/, /about, /api/data)
- req.headers — заголовки запроса (объект)
- Потоковое API для чтения тела запроса (для POST/PUT — позже)
Пример:
const server = http.createServer((req, res) => {
console.log('Метод:', req.method);
console.log('URL:', req.url);
console.log('Заголовки:', req.headers);
res.end('ok');
});
Объект ответа (res)
Объект res (response) позволяет отправлять ответ клиенту:
- res.writeHead(statusCode, headers) — установить статус и заголовки
- res.write(data) — отправить часть данных (можно несколько раз)
- res.end([data]) — завершить ответ, можно сразу отправить данные
Пример:
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('Строка 1\n');
res.write('Строка 2\n');
res.end('Финал!');
4. Практика: сервер с разными ответами по URL
Давайте сделаем сервер, который отвечает по-разному на разные URL. Это уже похоже на "ручную маршрутизацию" (будем разбирать подробнее в следующих лекциях).
const http = require('http');
const server = http.createServer((req, res) => {
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Главная страница</h1>');
} else if (req.url === '/about') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>О нас</h1>');
} else {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.end('<h1>404: Страница не найдена</h1>');
}
});
server.listen(3000, () => {
console.log('Сервер запущен на http://localhost:3000');
});
Что изменилось:
- Мы добавили простую логику: если URL — это /, отвечаем "Главная страница". Если /about — "О нас". Для остальных — 404.
- Устанавливаем правильный статус (200 или 404).
- Меняем Content-Type на text/html, чтобы браузер отображал HTML.
5. Полезные нюансы
Что такое порт и почему 3000
Порт — это как "дверь" в вашем компьютере. Одна программа может слушать только один порт одновременно. По умолчанию веб-серверы используют порт 80 (HTTP) или 443 (HTTPS), но для разработки принято использовать "безопасные" порты вроде 3000, 4000, 8080 и т.д.
Если вы попробуете запустить два сервера на одном порту — получите ошибку EADDRINUSE (адрес уже используется).
Остановка сервера
Сервер будет работать, пока вы не остановите процесс (например, Ctrl+C в терминале). Если вы изменили код, нужно перезапустить сервер. Для автоматизации этого процесса часто используют утилиту nodemon (установите через npm install -g nodemon), которая перезапускает сервер при изменении файлов.
6. Типичные ошибки при создании http-сервера
Ошибка №1: не вызывать res.end()
Если забыть вызвать res.end(), соединение с клиентом "зависнет" — браузер будет ждать ответ бесконечно. Всегда заверяйте ответ этим методом, даже если не отправляете никаких данных.
Ошибка №2: неправильный Content-Type
Если отправлять HTML, но указать text/plain, браузер покажет "сырой" HTML. Если отправлять JSON, но не указать application/json, некоторые клиенты не смогут распарсить ответ. Следите за заголовками!
Ошибка №3: запуск нескольких серверов на одном порту
Порт — штука эксклюзивная. Если при запуске нового сервера видите ошибку EADDRINUSE, значит, порт уже занят. Остановите предыдущий сервер или выберите другой порт.
Ошибка №4: забыли обработать все методы/пути
Если ваш сервер обрабатывает только GET-запросы, а браузер или клиент отправил POST — сервер может отвечать неадекватно или падать. Проверяйте и req.method, и req.url!
Ошибка №5: не обрабатывать ошибки
Если в обработчике запроса возникла ошибка (например, синтаксическая или при чтении файла), сервер может "упасть". Используйте try/catch, логируйте ошибки и не бойтесь отправлять 500 — Internal Server Error.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ