Какие основные HTTP статус-коды класса 4xx (ошибки клиента) вы знаете?

Ответ

Коды состояния 4xx указывают на ошибку со стороны клиента (браузера, приложения). Сервер понял запрос, но не может его выполнить из-за проблемы в самом запросе.

Код Название Описание и типичный сценарий
400 Bad Request Сервер не может обработать запрос из-за неверного синтаксиса (например, некорректный JSON в теле запроса).
401 Unauthorized Для доступа к ресурсу требуется аутентификация, и она не предоставлена или не прошла. Часто сопровождается заголовком WWW-Authenticate.
403 Forbidden Сервер понял запрос и клиент аутентифицирован, но у него нет прав на доступ к данному ресурсу.
404 Not Found Сервер не нашел запрашиваемый ресурс (URL). Самый распространенный код.
405 Method Not Allowed Метод запроса (GET, POST и т.д.) не поддерживается для данного URL. Сервер должен вернуть заголовок Allow со списком разрешенных методов.
408 Request Timeout Сервер не дождался полного запроса от клиента в отведенное время.
409 Conflict Запрос конфликтует с текущим состоянием сервера (например, попытка создать ресурс, который уже существует, или редактирование устаревшей версии данных).
429 Too Many Requests Клиент отправил слишком много запросов за короткое время (превысил rate limit).

Пример проверки в автотесте (Python, pytest):

import pytest
import requests

@pytest.mark.parametrize("invalid_id, expected_code", [
    ("non_existent_123", 404),
    ("<script>alert(1)</script>", 400), # Проверка на некорректный ввод
    ("", 404),
])
def test_get_resource_with_invalid_id(invalid_id, expected_code):
    url = f"https://api.example.com/v1/users/{invalid_id}"
    response = requests.get(url)

    assert response.status_code == expected_code, 
        f"Ожидался статус {expected_code}, получен {response.status_code} для ID '{invalid_id}'"

Ответ 18+ 🔞

Ну, слушай, вот эти ваши коды 4xx — это вообще песня, блядь. Это когда клиент, этот, наш браузер или приложение, накосячило по полной программе. Сервер-то всё понял, он не дурак, но выполнить запрос не может, потому что от клиента пришла какая-то хуйня. Ёпта, классика жанра.

Смотри, какие у нас тут главные звезды эстрады:

  • 400 (Bad Request) — это когда ты серверу какую-то ахинею в рот суёшь. Типа отправил JSON, а там запятая лишняя или скобка не закрыта. Сервер смотрит на это и думает: «Мудак, блядь, что за пиздопроебибна? Я это читать не буду». И шлёт тебе 400.
  • 401 (Unauthorized) — «Ты кто такой, сука?». Ты не представился, не сказал пароль, не показал пропуск. Или показал, но он просроченный. Доступа нет, иди нахуй, авторизуйся сначала.
  • 403 (Forbidden) — А вот это уже интереснее. Ты вроде представился, пропуск есть, но... тебе в этот кабинет нельзя. У тебя нет прав. Ты стучишься в дверь к директору, а тебе говорят: «Вася, ты уборщик, блядь, иди мой сортиры». Вот это 403. Сервер тебя знает, но не пускает.
  • 404 (Not Found) — Король, блядь, всех ошибок! «Страница не найдена». Ты просишь то, чего нет. Искал site.com/gde_moi_dengi, а там пусто. Сервер честно говорит: «Чувак, нихуя такого по этому адресу нет. Может, тебе в зеркало посмотреть?».
  • 405 (Method Not Allowed) — Ты пришёл к банкомату и пытаешься его обнять (метод HUG), чтобы деньги выпали. А он тебе: «Мудила, я только GET (забери деньги) и POST (внеси деньги) понимаю». Вот это 405.
  • 408 (Request Timeout) — Сервер ждал-ждал, пока ты там свой запрос соберёшь, да так и не дождался. «Ну и иди нахуй со своим медленным интернетом», — думает он и рвёт соединение.
  • 409 (Conflict) — Попытка ебнуть систему. Хочешь создать пользователя с логином admin, а он уже есть. Или пытаешься изменить документ, который пока ты думал, уже кто-то другой изменил. Конфликт, блядь, версий или состояний. Разрули сначала.
  • 429 (Too Many Requests) — А это моё любимое. Ты, как конченый, долбишь сервер запросами. «ДАЙ ДАННЫЕ! ДАЙ БЫСТРЕЕ!». А сервер тебе: «Охуел, что ли? Успокойся, нахуй, подожди». Это rate limiting в действии.

А вот, смотри, как это в тестах выглядит, если ты, конечно, не лох и пишешь их:

import pytest
import requests

@pytest.mark.parametrize("invalid_id, expected_code", [
    ("non_existent_123", 404),
    ("<script>alert(1)</script>", 400), # Проверка на некорректный ввод
    ("", 404),
])
def test_get_resource_with_invalid_id(invalid_id, expected_code):
    url = f"https://api.example.com/v1/users/{invalid_id}"
    response = requests.get(url)

    assert response.status_code == expected_code, 
        f"Ожидался статус {expected_code}, получен {response.status_code} для ID '{invalid_id}'"

Вот тут мы, как хитрая жопа, подсовываем API разный бред: несуществующий айдишник (должен вернуть 404), кусок скрипта, будто мы хакеры ебаные (должен вернуть 400, потому что это хуйня, а не айди), и пустоту. И смотрим, не обосрётся ли наш сервер. Если статус код не тот — пишем красивое сообщение и ищем, кто накосячил. Всё просто, как три копейки, блядь.