1. Введение
Когда браузер или другое приложение делает запрос к серверу (например, к вашему Express API), сервер всегда отвечает не только данными, но и специальным статус-кодом. Этот код — как короткая записка: «Всё хорошо!», «Не нашёл то, что ты просил», «У меня тут что-то сломалось» и т.д.
Аналогия из жизни
Представьте, что вы заказали пиццу. Курьер приезжает и вручает вам коробку. Если всё хорошо — он улыбается (200), если пицца закончилась — приносит записку «Извините, нет в наличии» (404), а если по дороге уронил коробку — приносит извинения и объясняет, что случилось (500).
Основные группы HTTP-статусов
- 1xx — Информационные (в реальной жизни почти не встречаются, можно не переживать)
- 2xx — Успех (всё хорошо, запрос выполнен)
- 3xx — Перенаправления (редиректы)
- 4xx — Ошибка клиента (ты что-то сделал не так)
- 5xx — Ошибка сервера (у нас что-то сломалось)
Самые популярные коды, которые мы будем использовать:
- 200 OK — всё хорошо, данные отправлены.
- 201 Created — что-то успешно создано (например, новая задача).
- 404 Not Found — не нашли то, что просили.
- 500 Internal Server Error — на сервере что-то пошло не так.
Как отправить статус-код в Express
Express делает работу с HTTP-статусами очень простой. По умолчанию, если вы просто отправляете ответ через res.send() или res.json(), сервер возвращает статус 200 (OK).
Но если нужно отправить другой статус — используйте метод res.status(код). Этот метод возвращает объект ответа (res), поэтому можно сразу продолжить цепочку вызова.
Пример:
res.status(404).send('Такой страницы нет!');
Или с JSON:
res.status(201).json({ message: 'Задача создана!' });
2. Популярные HTTP-статусы и когда их использовать
| Код | Имя | Когда использовать |
|---|---|---|
|
OK | Всё прошло хорошо, данные возвращены |
|
Created | Ресурс успешно создан (POST, иногда PUT) |
|
No Content | Всё хорошо, но возвращать нечего (например, удаление) |
|
Bad Request | Клиент отправил некорректные данные |
|
Unauthorized | Необходима авторизация (нет токена/логина) |
|
Forbidden | Доступ запрещён (есть токен, но прав не хватает) |
|
Not Found | Ресурс не найден |
|
Conflict | Конфликт (например, такой пользователь уже существует) |
|
Internal Server Error | На сервере что-то сломалось |
3. Практика: отправляем разные статусы в нашем API
Давайте доработаем наш мини-REST API для задач. Пусть у нас есть массив задач, и мы умеем:
- Получать список задач (GET /tasks)
- Получать одну задачу по id (GET /tasks/:id)
- Создавать задачу (POST /tasks)
- Удалять задачу (DELETE /tasks/:id)
Исходная структура:
// app.js
const express = require('express');
const app = express();
app.use(express.json());
let tasks = [
{ id: 1, title: 'Купить хлеб', done: false },
{ id: 2, title: 'Выучить Express', done: false }
];
// ... маршруты будут ниже
Отправляем 200 OK
200 — это стандартный статус для успешного запроса. Express сам его ставит, если вы не указали другой. Но иногда для ясности лучше указать явно.
// Получить все задачи
app.get('/tasks', (req, res) => {
res.status(200).json(tasks); // Можно и просто res.json(tasks)
});
Отправляем 201 Created
201 — используем, когда что-то успешно создано (например, новая задача).
// Создать новую задачу
app.post('/tasks', (req, res) => {
const { title } = req.body;
if (!title) {
// Если не передали title — ошибка клиента
return res.status(400).json({ error: 'Поле title обязательно!' });
}
const newTask = {
id: Date.now(), // простая генерация id
title,
done: false
};
tasks.push(newTask);
// Возвращаем 201 и созданную задачу
res.status(201).json(newTask);
});
Отправляем 404 Not Found
404 — если не нашли нужный ресурс (например, задачи с таким id нет).
// Получить задачу по id
app.get('/tasks/:id', (req, res) => {
const id = Number(req.params.id);
const task = tasks.find(t => t.id === id);
if (!task) {
// Задача не найдена
return res.status(404).json({ error: 'Задача не найдена' });
}
res.status(200).json(task);
});
Отправляем 500 Internal Server Error
500 — если на сервере случилось что-то неожиданное (например, ошибка в коде).
В идеале, такие ошибки должны ловиться автоматически (например, через специальный middleware), но иногда можно отправлять их вручную.
// Удалить задачу по id
app.delete('/tasks/:id', (req, res) => {
const id = Number(req.params.id);
const index = tasks.findIndex(t => t.id === id);
if (index === -1) {
return res.status(404).json({ error: 'Задача не найдена' });
}
try {
// Имитация ошибки (например, если вдруг tasks не массив)
tasks.splice(index, 1);
res.status(200).json({ message: 'Задача удалена' });
} catch (err) {
// Что-то пошло не так
res.status(500).json({ error: 'Ошибка на сервере' });
}
});
4. Кратко: как отправить статус и ответ в Express
- res.status(код).send('Текстовый ответ')
- res.status(код).json({ ... })
- res.sendStatus(код) — отправляет только статус и короткое сообщение
Примеры:
res.sendStatus(404); // Только статус и "Not Found"
res.status(201).json({ id: 123 }); // Статус + JSON
res.status(400).send('Некорректный запрос'); // Статус + текст
5. Типичные ошибки при работе с HTTP-статусами
Ошибка №1: Всегда отправлять 200 OK, даже если что-то пошло не так.
Это сбивает с толку клиента. Если задача не найдена — отправляйте 404, если данные невалидны — 400.
Ошибка №2: Не завершать выполнение после отправки ответа с ошибкой.
Если написали res.status(404).json(...), обязательно добавьте return, иначе сервер может попытаться отправить ответ ещё раз и получить ошибку "Cannot set headers after they are sent".
Ошибка №3: Не обрабатывать неожиданные ошибки.
Если не добавить глобальный обработчик ошибок, Express просто завершит процесс при исключении. Всегда добавляйте app.use((err, req, res, next) => { ... }).
Ошибка №4: Использовать send вместо json для API.
Если ваше API возвращает данные, всегда используйте res.json(), чтобы клиенту было проще их парсить.
Ошибка №5: Путаница между 201 и 200.
201 — только если вы что-то создали (POST), 200 — если просто вернули данные.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ