Какие статусы HTTP-ответов вы знаете?

«Какие статусы HTTP-ответов вы знаете?» — вопрос из категории Сети, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В работе с веб-приложениями я постоянно имею дело с HTTP-статусами. Они сгруппированы в классы по первой цифре трехзначного кода. Правильное использование статусов критически важно для RESTful API и понимания клиентом результата его запроса.

Основные классы и часто используемые коды:

Класс Значение Ключевые примеры
1xx (Информационные) Запрос принят, процесс продолжается. 100 Continue (сервер готов принять тело запроса). Встречается редко.
2xx (Успех) Запрос успешно обработан. 200 OK – стандартный ответ для успешных GET, PUT, PATCH.
201 Created – ресурс создан (успешный POST). В ответе должен быть заголовок Location с URI нового ресурса.
204 No Content – сервер успешно обработал запрос, но не возвращает тело (успешный DELETE, иногда POST/PUT).
3xx (Перенаправление) Для завершения запроса требуется дополнительное действие (обычно – ещё один запрос). 301 Moved Permanently – URI ресурса изменился навсегда. Все последующие запросы должны использовать новый URI.
302 Found – временное перенаправление. Клиент должен использовать исходный URI для будущих запросов.
304 Not Modified – ответ на условный GET (If-Modified-Since), указывает, что ресурс не изменился. Клиент может использовать кешированную версию.
4xx (Ошибка клиента) Запрос содержит ошибку (неверный синтаксис, невалидные данные, недостаточно прав). 400 Bad Request – общая ошибка, сервер не может понять запрос (например, невалидный JSON).
401 Unauthorized – требуется аутентификация (клиент не представил учётные данные).
403 Forbidden – сервер понял запрос, но отказывается его авторизовать (прав недостаточно).
404 Not Found – ресурс по указанному URI не найден.
422 Unprocessable Entity (WebDAV) – запрос синтаксически верен, но содержит семантические ошибки (например, не пройдена валидация полей). Часто используется в API.
5xx (Ошибка сервера) Сервер не смог выполнить запрос из-за внутренней ошибки. 500 Internal Server Error – общая ошибка сервера, когда более конкретный код 5xx не подходит.
502 Bad Gateway – сервер, выступая в роли шлюза или прокси, получил неверный ответ от вышестоящего сервера.
503 Service Unavailable – сервер временно не может обрабатывать запросы (перегрузка, техобслуживание). Должен включать заголовок Retry-After.

Практический пример из моего опыта (Python/Flask API):

from flask import jsonify, abort

@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = db_session.query(User).get(user_id)

    if user is None:
        # Клиент запросил несуществующий ресурс
        abort(404, description="User not found")
        # Или можно вернуть JSON:
        # return jsonify({"error": "User not found"}), 404

    if not current_user.has_permission('view', user):
        # У клиента нет прав на просмотр этого ресурса
        abort(403)

    # Успешный ответ
    return jsonify(user.to_dict()), 200

@app.route('/api/users', methods=['POST'])
def create_user():
    data = request.get_json()

    if not data:
        abort(400, description="No JSON data provided")

    # ... валидация данных ...
    if validation_errors:
        # Данные не прошли бизнес-валидацию
        return jsonify({"errors": validation_errors}), 422

    new_user = User(**data)
    db_session.add(new_user)
    db_session.commit()

    # Ресурс создан, возвращаем его данные и статус 201
    return jsonify(new_user.to_dict()), 201