Модуль http: первый сервер
Веб-сервер — программа, которая ждёт запросы от браузеров и отправляет ответы. В Node.js он пишется в несколько строк на встроенном модуле node:http. Фреймворки вроде Express построены поверх этого модуля, поэтому, разобравшись в нём, вы будете понимать, что они делают за вас.
Простейший сервер
Создайте файл src/server.js:
// src/server.js
import http from 'node:http';
const server = http.createServer((req, res) => {
res.end('Привет от блога!');
});
server.listen(3000, () => {
console.log('Сервер запущен: http://localhost:3000');
});Запустите его командой node src/server.js и откройте http://localhost:3000 в браузере — появится текст «Привет от блога!». Программа не завершается: она ждёт запросы, пока вы не нажмёте Ctrl+C.
Запрос и ответ
Функция, переданная в createServer(), вызывается на каждый запрос. Она получает два объекта:
| Объект | Что это | Главное |
|---|---|---|
req | Запрос от браузера | req.method, req.url, req.headers |
res | Ответ, который вы собираете | res.statusCode, res.setHeader(), res.end() |
res.end() отправляет тело ответа и завершает его. Без этого вызова браузер будет ждать бесконечно.
Код состояния и заголовки
Перед телом ответа отправляют код состояния и заголовки. Заголовок Content-Type сообщает браузеру, что именно он получил:
// src/server.js
import http from 'node:http';
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>Блог Анны</h1><p>Скоро здесь будут статьи.</p>');
});
server.listen(3000);Теперь браузер покажет заголовок и абзац, а не текст с тегами. charset=utf-8 нужен, чтобы кириллица не превратилась в нечитаемые символы.
Что пришло в запросе
Выведите в терминал метод и адрес каждого запроса — это простейший журнал сервера:
// src/server.js
import http from 'node:http';
const server = http.createServer((req, res) => {
console.log(req.method, req.url);
res.end('ok');
});
server.listen(3000);Откройте http://localhost:3000/posts?page=2 — в терминале появится GET /posts?page=2. Браузер может прислать и второй запрос, GET /favicon.ico, за значком сайта.
Порт из окружения
На сервере порт задают переменной окружения, поэтому номер не вписывают жёстко:
// src/server.js
const PORT = Number(process.env.PORT ?? 3000);
server.listen(PORT, () => console.log(`http://localhost:${PORT}`));Коды состояния
| Код | Значение |
|---|---|
200 | Всё в порядке |
201 | Создано |
400 | Ошибка в запросе |
404 | Не найдено |
500 | Ошибка на сервере |
Частая ошибка
Если порт уже занят — например, сервер запущен во втором окне терминала, — программа упадёт:
Error: listen EADDRINUSE: address already in use :::3000Остановите прежний сервер сочетанием Ctrl+C или запустите новый на другом порту: PORT=3001 node src/server.js.