Структура HTTP-запроса
Структура HTTP-запроса
HTTP-запрос — это текст, который браузер отправляет серверу. Каждый раз, когда ты открываешь сайт, кликаешь по ссылке или отправляешь форму, генерируется новый HTTP-запрос. Разберём его анатомию построчно.
Три части HTTP-запроса
HTTP-запрос состоит из трёх секций, разделённых переводами строк:
- Стартовая строка (request line) — метод, путь и версия протокола.
- Заголовки (headers) — метаданные запроса, по одному на строку.
- Тело (body) — данные запроса. Присутствует не всегда (в GET его нет).
GET /search?q=http HTTP/1.1 ← стартовая строка
Host: www.google.com ← заголовки
User-Agent: Mozilla/5.0 ...
Accept: text/html
Accept-Language: ru
← пустая строка — конец заголовков
← тело (в GET отсутствует)
Стартовая строка
Стартовая строка содержит три элемента:
МЕТОД ПУТЬ ВЕРСИЯ_ПРОТОКОЛА
GET /search?q=http HTTP/1.1
- Метод (method). Что мы хотим сделать:
GET— получить,POST— отправить,DELETE— удалить. Подробно — в уроке 5-5. - Путь (path). Какой ресурс запрашиваем:
/,/search,/images/logo.png. Может включать query-параметры после?. - Версия протокола.
HTTP/1.1,HTTP/2(для HTTP/2 структура бинарная, но инструменты показывают текстовое представление).
Заголовки запроса
Заголовки — это метаданные в формате Имя: Значение. Самые важные:
Host — единственный обязательный заголовок в HTTP/1.1. Указывает домен, к которому обращается клиент. Без него невозможно держать несколько сайтов на одном IP (virtual hosting):
Host: www.example.com
User-Agent — идентифицирует клиента: браузер, операционную систему, движок. Раньше использовался для адаптации сайтов, сегодня — в основном для статистики:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
Accept — какие форматы данных клиент готов принять. Сервер использует это для Content Negotiation — выбора формата ответа:
Accept: text/html, application/json
Accept-Language: ru, en;q=0.9
Accept-Encoding: gzip, br
q=0.9 — это приоритет (quality factor): «русский предпочтительнее английского».
Content-Type — формат данных в теле запроса. Присутствует, только если есть тело (POST, PUT):
Content-Type: application/json
Content-Type: application/x-www-form-urlencoded
Content-Length — размер тела в байтах. Нужен, чтобы сервер знал, сколько данных читать из TCP-потока:
Content-Length: 348
Authorization — данные для аутентификации: Basic-токен, Bearer-токен или другие схемы:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Как выглядит реальный запрос
Вот полный HTTP-запрос, который браузер отправляет при заходе на главную страницу Google:
GET / HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: text/html,application/xhtml+xml
Accept-Language: ru-RU,ru;q=0.9
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: NID=511=abc123; CONSENT=YES+
Обрати внимание: запрос полностью текстовый. Ты можешь прочитать его глазами — именно это делает HTTP доступным для отладки.
GET-запрос с query-параметрами
Когда ты вводишь что-то в поиск, браузер формирует GET-запрос с параметрами в URL:
GET /search?q=http+protocol&lang=ru HTTP/1.1
Host: www.google.com
Параметры после ? называются query string: ключ=значение, разделённые &. Пробелы и спецсимволы кодируются (пробел → + или %20).
POST-запрос с телом
Когда ты отправляешь форму логина, браузер формирует POST-запрос:
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
username=stepan&password=secret
В отличие от GET, данные передаются в теле запроса, а не в URL. Поэтому пароль не виден в адресной строке (но виден в теле — без HTTPS он передаётся открытым текстом).
Проверь себя
- Какой заголовок HTTP/1.1 является обязательным?
- Чем GET-запрос с параметрами отличается от POST с телом?
- Зачем нужен заголовок
Content-Length?
Host. Он указывает домен, к которому обращается клиент, и позволяет серверу с одним IP обслуживать несколько сайтов.- В GET параметры в URL (видны в адресной строке, кэшируются, ограничены по длине). В POST данные в теле запроса (не видны в URL, не кэшируются, не ограничены по длине).
- Сервер должен знать, сколько байт читать из TCP-потока после заголовков. Без этого пришлось бы использовать другой способ определения конца тела (chunked transfer encoding).
Что унести с урока
- HTTP-запрос состоит из стартовой строки, заголовков и (опционально) тела.
- Стартовая строка: метод, путь, версия протокола.
Host— обязательный заголовок HTTP/1.1.User-Agent,Accept,Content-Type— ключевые для работы.- GET передаёт параметры в URL, POST — в теле запроса.
Мы знаем, что отправляет клиент. В следующем уроке разберём, что присылает в ответ сервер — структуру HTTP-ответа.