1. Как Express.js работает с телом запроса?
Когда браузер или другой клиент отправляет запрос на сервер, он может передавать не только URL и параметры в строке запроса, но и содержимое тела запроса. Это особенно актуально для методов POST, PUT, PATCH — там обычно передаются данные, которые нужно создать или обновить.
Примеры:
- Пользователь заполняет форму регистрации и отправляет её — данные формы приходят на сервер в теле запроса.
- Клиентское приложение отправляет JSON с новой задачей в todo-листе — опять же, данные приходят в теле запроса.
Аналогия:
Если URL и query-параметры — это адрес и надписи на посылке, то тело запроса — это содержимое самой посылки.
Детали работы Express
В Express.js для удобства работы с телом запроса используется специальное свойство объекта запроса: req.body. Именно сюда попадают все данные, которые были отправлены клиентом в теле запроса.
Важный момент:
По умолчанию Express не умеет читать тело запроса! Для этого нужно явно подключить соответствующий middleware:
- express.json() — для разбора JSON-данных.
- express.urlencoded() — для разбора данных, отправленных из HTML-форм (формат application/x-www-form-urlencoded).
Без этих middleware свойство req.body будет всегда undefined, и никакие данные вы не получите. Это одна из самых популярных "ловушек" у новичков!
Подключение middleware для разбора тела запроса
Вот как это выглядит в коде:
const express = require('express');
const app = express();
// Подключаем middleware для разбора JSON
app.use(express.json());
// Подключаем middleware для разбора данных форм
app.use(express.urlencoded({ extended: true }));
// Теперь req.body будет доступен во всех маршрутах ниже!
- express.json() — разбирает тело запроса, если оно отправлено в формате JSON (Content-Type: application/json).
- express.urlencoded({ extended: true }) — разбирает данные, отправленные из обычных HTML-форм.
Пояснение про { extended: true }:
Если указать extended: false, будет использоваться более простой парсер (без поддержки вложенных объектов). Обычно используют true, чтобы не ограничивать себя.
2. Пример: Обработка POST-запроса с JSON-данными
Давайте добавим в наше приложение маршрут, который принимает новую задачу в формате JSON и добавляет её в массив задач.
Пример кода
const express = require('express');
const app = express();
app.use(express.json()); // <--- обязательно!
// Массив задач
let todos = [
{ id: 1, text: 'Купить хлеб', completed: false },
{ id: 2, text: 'Выучить Node.js', completed: false }
];
// POST /todos — добавление новой задачи
app.post('/todos', (req, res) => {
// req.body — это объект с данными из запроса
const { text } = req.body;
if (!text) {
// Если поле text не передано — ошибка
return res.status(400).json({ error: 'Поле text обязательно' });
}
const newTodo = {
id: todos.length + 1,
text,
completed: false
};
todos.push(newTodo);
// Возвращаем новую задачу клиенту
res.status(201).json(newTodo);
});
app.listen(3000, () => {
console.log('Сервер запущен на http://localhost:3000');
});
Как это работает?
- Клиент отправляет POST-запрос на /todos с телом:
{ "text": "Погладить кота" } - Express, благодаря express.json(), автоматически парсит тело и кладёт его в req.body.
- Мы достаём text из req.body и создаём новую задачу.
- Если поле не передано, возвращаем ошибку 400.
- Всё просто, удобно и без магии!
3. Пример: Обработка данных из HTML-формы (application/x-www-form-urlencoded)
Если вы отправляете данные не как JSON, а через обычную форму (например, из браузера), данные будут закодированы иначе. Для этого нужен второй middleware — express.urlencoded().
Код
const express = require('express');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.post('/feedback', (req, res) => {
// req.body теперь содержит поля из формы
const { name, message } = req.body;
if (!name || !message) {
return res.status(400).send('Все поля обязательны!');
}
// Здесь можно сохранить отзыв в базу или массив
res.send(`Спасибо, ${name}, ваш отзыв получен!`);
});
Как это работает?
Если отправить форму:
<form action="/feedback" method="post">
<input name="name" placeholder="Ваше имя">
<textarea name="message"></textarea>
<button type="submit">Отправить</button>
</form>
Поля name и message появятся в req.body как обычные свойства объекта.
4. Полезные нюансы
Как проверить, что приходит в req.body?
Очень просто! Добавьте в обработчик такую строчку:
console.log(req.body);
Это поможет увидеть, что именно присылает клиент. Для отладки — незаменимо.
Совместное использование express.json() и express.urlencoded()
Можно и нужно использовать оба middleware, если ваше приложение должно принимать и JSON, и данные из форм:
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
Express сам определит, какой парсер использовать, в зависимости от типа запроса.
Как это связано с нашим приложением?
В нашем учебном todo-приложении мы теперь можем реализовать добавление задач через POST-запросы. Например, фронтенд на React или Angular может отправлять новые задачи как JSON, а сервер будет их принимать через req.body.
Пример запроса с клиента (fetch):
fetch('/todos', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ text: 'Погладить кота' })
});
5. Типичные ошибки при работе с req.body
Ошибка №1: забыли подключить middleware.
Самая частая проблема: вы пишете req.body, а там всегда undefined. Почти всегда это значит, что забыли добавить app.use(express.json()) или app.use(express.urlencoded()) в начало файла.
Ошибка №2: неправильный Content-Type.
Если клиент отправляет JSON, но не указал заголовок 'Content-Type: application/json', Express не сможет распарсить тело, и req.body будет пустым. Аналогично с формами.
Ошибка №3: неверный порядок middleware.
Middleware должны быть подключены ДО маршрутов, которые используют req.body. Если вы подключите их после, данные не будут доступны.
Ошибка №4: пытаетесь читать тело в GET-запросах.
По стандарту тело запроса обычно используется только с POST, PUT, PATCH. В GET-запросах тело либо отсутствует, либо игнорируется.
Ошибка №5: забыли проверять данные из req.body.
Не доверяйте данным "вслепую"! Всегда проверяйте, что нужные поля пришли, и что они корректны — иначе ваш сервер может упасть или принять "кривые" данные.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ