HTTP: методы, статусы, заголовки

Разбираем главный протокол веба: как устроен HTTP-запрос и ответ, методы, статус-коды и заголовки.

HTTP (HyperText Transfer Protocol) — текстовый протокол прикладного уровня по схеме «запрос — ответ»: клиент шлёт запрос, сервер возвращает ответ.

Как выглядит запрос

HTTP-запрос — это обычный текст. Первая строка содержит метод, путь и версию; дальше — заголовки; затем (необязательно) тело:

GET /catalog/items?page=2 HTTP/1.1
Host: shop.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Cookie: session=abc123

(тело пустое для GET)

Как выглядит ответ

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 27
Cache-Control: max-age=3600

{"items": [], "page": 2}

Первая строка ответа — версия, числовой статус-код и его текст. Дальше заголовки и тело (тут — JSON).

Методы (глаголы)

МетодСмыслИдемпотентность
GETполучить ресурсда, без побочных эффектов
POSTсоздать / отправить данныенет
PUTзаменить ресурс целикомда
PATCHчастично изменитьнет (обычно)
DELETEудалить ресурсда

Идемпотентность — повтор запроса даёт тот же результат. GET, PUT, DELETE идемпотентны; POST — нет (два POST создадут две записи). Это влияет на безопасность повторов при сбоях.

Статус-коды по классам

Код ответа всегда трёхзначный, и его первая цифра задаёт класс. Покажем логику классификации на Python:

def status_class(code):
    return {1: 'информационный', 2: 'успех', 3: 'перенаправление',
            4: 'ошибка клиента', 5: 'ошибка сервера'}[code // 100]

for code in [200, 301, 404, 500]:
    print(f'{code} -> {status_class(code)}')

Вывод:

200 -> успех
301 -> перенаправление
404 -> ошибка клиента
500 -> ошибка сервера

Запоминать удобно по первой цифре: 2xx — всё хорошо, 3xx — иди по другому адресу, 4xx — ты ошибся (клиент), 5xx — сервер сломался. Частые: 200 OK, 301 Moved Permanently, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error.

Заголовки

Заголовки — пары «ключ: значение», передающие метаданные. Примеры: Content-Type (формат тела), Authorization (учётные данные), Cache-Control (кэширование), Cookie/Set-Cookie (сессии). Заголовок Authorization: Basic — это просто закодированный в base64 «логин:пароль»:

import base64

creds = 'admin:secret'
encoded = base64.b64encode(creds.encode()).decode()
print('Логин:пароль:', creds)
print('Заголовок:    Authorization: Basic', encoded)
print('Декодируем:  ', base64.b64decode(encoded).decode())

Вывод:

Логин:пароль: admin:secret
Заголовок:    Authorization: Basic YWRtaW46c2VjcmV0
Декодируем:   admin:secret

Важно: base64 — это кодирование, а не шифрование. Любой может декодировать обратно. Поэтому Basic Auth безопасен только поверх HTTPS.

HTTP без состояния (stateless)

Ключевое свойство HTTP: каждый запрос независим, сервер по умолчанию не помнит предыдущие. Это упрощает масштабирование (любой сервер обработает любой запрос), но создаёт проблему: как узнать «залогиненного» пользователя между запросами? Ответ — cookies и сессии (следующий урок).

Итог

  • HTTP — текстовый протокол «запрос — ответ» прикладного уровня.
  • Методы: GET (читать), POST (создавать), PUT/PATCH (менять), DELETE (удалять).
  • Статусы по классам: 2xx успех, 3xx редирект, 4xx ошибка клиента, 5xx ошибка сервера.
  • HTTP stateless: сервер не помнит запросы между собой — состояние держат cookies/сессии.
Проверьте себя
1. Какой класс у статус-кода 404?
AУспех (2xx)
BПеренаправление (3xx)
CОшибка клиента (4xx)
DОшибка сервера (5xx)
2. Что означает, что HTTP — протокол без состояния (stateless)?
AОн не передаёт данные
BКаждый запрос независим, сервер по умолчанию не помнит предыдущие
CОн не использует заголовки
DОн не работает с cookies
3. Чем метод GET отличается от POST?
AGET создаёт данные, POST читает
BGET получает ресурс и идемпотентен, POST отправляет/создаёт данные и не идемпотентен
CОни идентичны
DPOST нельзя использовать в браузере
4. Безопасно ли передавать Basic Auth (base64 от логин:пароль) по обычному HTTP?
AДа, base64 — это шифрование
BНет, base64 легко декодируется обратно — нужен HTTPS
CДа, пароль скрыт навсегда
DБазовая авторизация вообще не передаёт пароль
Поддержать проект