HTTP-запрос
HTTP-запрос — это структурированное сообщение, отправляемое клиентом (например, веб-браузером, мобильным приложением или поисковым роботом) на сервер с целью получения или передачи данных, инициирующее взаимодействие по протоколу передачи гипертекста (HTTP). HTTP-запрос является фундаментальной единицей обмена информацией в вебе, следуя модели «клиент-сервер», где клиент выступает инициатором соединения.
Структура HTTP-запроса
Каждый HTTP-запрос состоит из нескольких обязательных и опциональных компонентов, которые передаются в виде текстовых строк, разделённых символами перевода строки (CRLF).
Стартовая строка (Request Line)
Первая строка запроса задаёт его основную цель. Она включает три элемента:
- Метод HTTP (HTTP Method) — глагол, указывающий на желаемое действие с ресурсом.
- URI (Uniform Resource Identifier) — путь к запрашиваемому ресурсу на сервере (например,
/index.htmlили/api/users). - Версия протокола (HTTP Version) — версия HTTP, используемая клиентом (например,
HTTP/1.1,HTTP/2).
Пример стартовой строки: `` GET /images/logo.png HTTP/1.1 ``
Заголовки (Headers)
Заголовки представляют собой набор пар «ключ: значение», которые передают метаданные о запросе, клиенте и ожидаемом ответе. Они следуют за стартовой строкой, каждый с новой строки. Конец блока заголовков обозначается пустой строкой.
Основные категории заголовков:
- General Headers (общие): применяются как к запросу, так и к ответу (например,
Date,Cache-Control). - Request Headers (заголовки запроса): содержат информацию о запросе и клиенте (например,
Host,User-Agent,Accept,Authorization). - Entity Headers (заголовки сущности): описывают содержимое тела запроса (например,
Content-Type,Content-Length).
Пример заголовков: `` Host: ru.wikipedia.org User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Accept: text/html,application/xhtml+xml Accept-Language: ru-RU,ru;q=0.9 ``
Тело запроса (Body)
Тело запроса является опциональным и используется для передачи данных на сервер. Оно присутствует в запросах, которые изменяют состояние сервера или создают новые ресурсы (например, методы POST, PUT, PATCH). Тело может содержать данные в различных форматах: JSON, XML, URL-кодированные параметры формы, бинарные файлы и т.д. Наличие тела обязательно сопровождается заголовком Content-Type, указывающим формат данных, и Content-Length, указывающим его размер.
Методы HTTP
Метод HTTP определяет семантику запроса. Наиболее распространённые методы регламентированы стандартом RFC 7231 и последующими спецификациями:
- GET — запрашивает представление указанного ресурса. Не должен изменять состояние сервера (идемпотентен). Является самым часто используемым методом.
- HEAD — аналогичен GET, но сервер возвращает только заголовки ответа без тела. Используется для проверки доступности ресурса или получения метаданных.
- POST — отправляет данные на сервер для обработки (например, создание нового ресурса, отправка формы). Может изменять состояние сервера и не является идемпотентным.
- PUT — заменяет текущее представление ресурса данными, переданными в теле запроса. Идемпотентен.
- DELETE — удаляет указанный ресурс. Идемпотентен.
- PATCH — применяет частичные изменения к ресурсу. Отличается от PUT тем, что передаёт не полную замену, а набор инструкций по модификации.
- OPTIONS — запрашивает информацию о поддерживаемых сервером методах для указанного ресурса.
- CONNECT — устанавливает туннель к серверу, часто используемый для HTTPS-соединений через прокси.
Версии протокола и их влияние на запросы
HTTP/0.9
Первая версия, крайне примитивная. Запрос состоял только из метода GET и пути к ресурсу. Заголовки и версия протокола отсутствовали.
HTTP/1.0
Ввёл версию протокола, заголовки и метод POST. Каждый запрос требовал установки нового TCP-соединения, что снижало производительность.
HTTP/1.1
Стандарт, доминировавший в вебе на протяжении десятилетий. Ключевые нововведения:
- Постоянные соединения (Persistent Connections): возможность отправлять несколько запросов и получать ответы в рамках одного TCP-соединения.
- Конвейеризация (Pipelining): отправка нескольких запросов без ожидания ответов на предыдущие (реализована не полностью из-за проблем с «блокировкой начала очереди» — Head-of-Line blocking).
- Обязательный заголовок
Host: позволил размещать несколько веб-сайтов на одном IP-адресе (виртуальный хостинг). - Новые методы: PUT, DELETE, OPTIONS, CONNECT.
HTTP/2
Кардинально изменил формат передачи, перейдя от текстового к бинарному (фреймы). Основные особенности:
- Мультиплексирование: несколько запросов и ответов могут передаваться одновременно по одному TCP-соединению, что решает проблему блокировки начала очереди.
- Сжатие заголовков (HPACK): уменьшает объём передаваемых метаданных.
- Server Push: сервер может отправлять ресурсы клиенту до того, как они будут явно запрошены.
HTTP/3
Использует транспортный протокол QUIC (основанный на UDP) вместо TCP. Это обеспечивает:
- Снижение задержек при установке соединения (0-RTT в некоторых случаях).
- Устойчивость к потере пакетов: потеря одного пакета не блокирует передачу других потоков.
- Встроенное шифрование.
Примеры HTTP-запросов
Простой GET-запрос
`` GET /wiki/HTTP HTTP/1.1 Host: ru.wikipedia.org ``
POST-запрос с данными формы
``` POST /login HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Content-Length: 27
username=user&password=12345 ```
Запрос с авторизацией (Bearer Token)
`` GET /api/private/data HTTP/1.1 Host: api.example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``
Жизненный цикл HTTP-запроса
- Разрешение DNS: клиент преобразует доменное имя из URL в IP-адрес сервера.
- Установка TCP-соединения: между клиентом и сервером выполняется тройное рукопожатие (SYN, SYN-ACK, ACK).
- Для HTTPS — установка TLS-соединения: выполняется рукопожатие TLS для согласования шифрования и обмена сертификатами.
- Отправка запроса: клиент формирует и отправляет HTTP-запрос через установленное соединение.
- Обработка на сервере: веб-сервер (например, Nginx, Apache) принимает запрос, анализирует его и передаёт приложению (например, на PHP, Python, Java) для генерации ответа.
- Получение ответа: сервер отправляет HTTP-ответ, содержащий статус-код, заголовки и тело.
- Закрытие соединения: в HTTP/1.0 соединение закрывается после ответа. В HTTP/1.1 и выше оно может оставаться открытым для последующих запросов.
Безопасность HTTP-запросов
Протокол HTTP сам по себе не обеспечивает шифрования, поэтому данные передаются в открытом виде. Для защиты используется протокол HTTPS (HTTP over TLS), который шифрует всё содержимое запроса и ответа. При использовании HTTPS перехватчик может видеть только IP-адрес сервера и, возможно, доменное имя (из-за SNI — Server Name Indication), но не URI, заголовки или тело запроса.
Также существуют механизмы защиты от подделки запросов:
- CSRF-токены (Cross-Site Request Forgery): случайные строки, встраиваемые в формы, которые проверяются сервером.
- Заголовок
OriginиReferer: позволяют серверу определить, с какого сайта был отправлен запрос. - Политика CORS (Cross-Origin Resource Sharing): механизм, с помощью которого сервер разрешает или запрещает запросы с других доменов.
Интересные факты
- Максимальный размер URI в HTTP/1.1 не регламентирован стандартом, но на практике большинство серверов ограничивают его 8 КБ.
- Заголовок
User-Agentчасто используется для статистики и адаптации контента под разные браузеры, но может быть легко подделан. - Метод
TRACEбыл исключён из стандарта безопасности из-за уязвимости к атакам типа Cross-Site Tracing (XST). - Первый HTTP-запрос в истории был отправлен Тимом Бернерсом-Ли в 1989 году для тестирования его протокола.
Источники
- RFC 7230 — Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
- RFC 7231 — Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
- RFC 7540 — Hypertext Transfer Protocol Version 2 (HTTP/2)
- RFC 9000 — QUIC: A UDP-Based Multiplexed and Secure Transport
- «HTTP: The Definitive Guide» by David Gourley and Brian Totty, O'Reilly Media
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →