HTTP с нуля: запрос, методы, статусы, cookies
Ты уже сто раз дёргал fetch и видел 200 OK. Этот урок переворачивает
картинку: HTTP это не магия браузера, а простой текстовый протокол, который
ты можешь набрать руками в терминале. Когда понимаешь, из чего собран запрос,
перестаёшь гадать, почему сервер вернул 403 вместо 401, и почему форма
улетела не туда.
Раздел открывается с самого низа стека прикладного уровня и идёт вглубь: сегодня HTTP как текст, дальше потоковые протоколы, потом транспорт и TLS, в конце эволюция до HTTP/3.
Идея: HTTP это текст и пара ролей
HTTP устроен предельно просто. Есть две роли: клиент шлёт запрос, сервер шлёт ответ. Один запрос, один ответ. Никакого состояния между ними протокол сам по себе не хранит, он stateless.
Запрос это просто текст из трёх частей:
GET /search?q=cats HTTP/1.1
Host: example.com
User-Agent: curl/8.4.0
Accept: text/html
- Стартовая строка: метод, путь с query, версия протокола.
- Заголовки: пары
Имя: значение, по одной на строку. - Пустая строка, затем тело (у
GETтела обычно нет).
Ответ симметричен:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1256
<!doctype html>...
Стартовая строка ответа несёт версию, числовой
статус-код
и его текстовое имя (OK, Not Found). Всё.
Демонстрация: набираем запрос руками
Лучший способ поверить, что это текст, набрать его самому. Открой терминал:
# самый честный способ увидеть сырой обмен
curl -v https://example.com
# совсем руками, без curl: открываем TCP и печатаем запрос
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' \
| nc example.com 80
В выводе curl -v строки с > это то, что ушло на сервер, строки с < это
ответ. Обрати внимание на \r\n в ручном варианте: HTTP требует именно
CRLF
как разделитель строк, а пустая строка \r\n\r\n отделяет заголовки от тела.
Методы: глаголы и их обещания
Метод это глагол. Он говорит серверу, что ты хочешь сделать с ресурсом по указанному пути. Важны не сами буквы, а два свойства, которые метод обещает.
- Safe: метод ничего не меняет. Прочитал и ушёл.
- Idempotent: повтор не добавляет эффекта.
| Метод | Safe | Idempotent | Зачем |
|---|---|---|---|
GET | да | да | прочитать ресурс |
HEAD | да | да | как GET, но только заголовки, без тела |
OPTIONS | да | да | спросить, что разрешено (используется CORS preflight) |
POST | нет | нет | создать, отправить, запустить действие |
PUT | нет | да | полностью заменить ресурс |
PATCH | нет | нет | частично изменить ресурс |
DELETE | нет | да | удалить ресурс |
Почему это не занудство, а основа надёжности: если сеть моргнула и ответ
потерялся, клиент может безопасно повторить GET, PUT или DELETE. А вот
POST повторять опасно, можно создать дубль заказа. Поэтому платёжки и очереди
вокруг POST городят
ключи идемпотентности.
PUT против PATCH: PUT посылает ресурс целиком и заменяет его, поэтому два
одинаковых PUT дают тот же результат. PATCH шлёт только дельту, и повтор
дельты может быть неоднозначным (например, increment), поэтому он не
идемпотентен по умолчанию.
Статусы: первая цифра решает всё
Не нужно зубрить все коды. Достаточно помнить, что задаёт первая цифра, и держать в голове десяток ходовых.
- 2xx, успех.
200 OKобычный ответ с телом.201 Createdсоздали ресурс, вLocationадрес нового.204 No Contentуспех без тела (типично дляDELETEилиPUT).206 Partial Contentотдали кусок (докачка, видео). - 3xx, перенаправление.
301переехали навсегда (браузер и поисковик запомнят),302/303временно,304 Not Modifiedотвечает на условный запрос: у тебя уже свежая копия, бери из кеша.307/308строго сохраняют метод и тело при редиректе (в отличие от301/302, которые исторически превращалиPOSTвGET). - 4xx, виноват клиент.
400кривой запрос,401 Unauthorizedты не представился (нет или плохой токен),403 Forbiddenпредставился, но прав нет,404ресурса нет,409 Conflictконфликт состояния (версия устарела),422 Unprocessableтело синтаксически валидно, но не проходит правила,429 Too Many Requestsтебя притормозили лимитом. - 5xx, виноват сервер.
500упал,502 Bad Gatewayпрокси получил мусор от апстрима,503 Service Unavailableперегружен или на обслуживании,504 Gateway Timeoutапстрим не ответил вовремя.
Главная пара, которую путают на собеседовании:
401 это про
аутентификацию
(кто ты), 403 это про
авторизацию
(что тебе можно). Нет токена, 401. Токен есть, но это чужая папка, 403.
дальше после входа
Урок целиком открыт всем, кто вошёл. Войди по своему email, чтобы читать дальше.
Вход пока по приглашению. Если хочешь учиться, напиши Vassiliy.