HTTP: от версии 1.1 до HTTP/3
HTTP (HyperText Transfer Protocol) — главный протокол прикладного уровня (уровень 7 модели OSI), на котором построена работа веба. За свою историю он прошёл несколько версий, каждая из которых решала ограничения предыдущей.
HTTP/1

HTTP/1 — это текстовый протокол. Каждое сообщение (запрос или ответ) представляет собой обычный текст, отформатированный переносами строк.
Структура HTTP-запроса:
- Start line (первая строка). Содержит:
- HTTP-глагол (GET, POST, PUT, DELETE и т. д.).
- Эндпоинт (путь к ресурсу, например
/api/users). - Версию протокола.
- Заголовки (headers) — блок ключ-значение с дополнительной информацией.
- Пустая строка — разделитель между заголовками и телом.
- Тело (body) — содержимое запроса (если есть, например, в POST-запросах).
HTTP-ответ устроен аналогично:
- Start line — версия протокола и статус-код (например,
200 OK). - Заголовки.
- Пустая строка.
- Тело ответа (если есть).
Эта простая текстовая структура лежит в основе всего, что строится поверх HTTP, и влияет на то, как мы используем протокол.
Как HTTP/1 работает «под капотом»

Принцип работы HTTP/1 — запрос-ответ (request-response). Клиент (неважно, фронт или бэк) инициирует взаимодействие:
- Создаётся TCP-соединение (connection). Важно: HTTP-соединения как такового не существует. Есть TCP-соединение, поверх которого передаются HTTP-сообщения. Фразы вроде «HTTP-коннект» или «WebSocket-коннект» — это неформальные обозначения того же самого TCP-соединения.
- Клиент отправляет HTTP-запрос в рамках этого TCP-соединения.
- Сервер обрабатывает запрос и отправляет ответ.
- После получения ответа соединение закрывается.
Это стандартный, самый простой сценарий работы. Однако у него есть очевидный недостаток: на каждый запрос требуется новое TCP-соединение, со всеми накладными расходами на handshake и т. д. Решением стал механизм Keep-Alive.
Что такое Keep-Alive
Keep-Alive (иногда называют persistent connection) — это механизм, который позволяет не закрывать TCP-соединение после отправки ответа на запрос. Фактически это набор заголовков, которые клиент и сервер могут обмениваться, чтобы договориться: «сохрани соединение».
Зачем нужен Keep-Alive? Создание нового TCP-соединения — дорогая операция (handshake, выделение ресурсов). Если мы знаем, что в ближайшее время будет серия запросов к одному серверу, гораздо эффективнее использовать одно и то же соединение для нескольких последовательных запросов-ответов, чем каждый раз открывать новое.
Настраивается Keep-Alive через заголовки, в которых можно указать:
- Максимальное время жизни соединения (тайм-аут).
- Максимальное количество запросов, которое можно передать по одному соединению.
- Максимальную паузу между запросами, после которой соединение будет закрыто.
Важная особенность HTTP/1 — строгая последовательность
Несмотря на Keep-Alive, HTTP/1 остаётся строго последовательным протоколом типа «запрос-ответ». Это значит, что:
- Клиент отправляет первый запрос.
- Ждёт ответ.
- Только после получения ответа может отправить следующий запрос.
- И так далее — запросы не могут передаваться параллельно в рамках одного соединения.
Таким образом, Keep-Alive избавляет от повторных handshake, но не решает проблему последовательного ожидания.
Проблема: неэффективное использование соединения
Когда сервер обрабатывает запрос, соединение висит вхолостую — данные по сети не передаются, а ресурсы соединения (память, процессор) заняты. Если у нас много последовательных запросов, время простоя соединения накапливается.
Логичное решение — отправлять несколько запросов параллельно. Самое простое (и грубое) решение: открыть несколько TCP-соединений одновременно и выполнять запросы в них параллельно.
Но у этого подхода есть минусы:
- Ограничения на количество одновременных соединений. Есть лимиты как со стороны клиента (браузер может ограничивать число параллельных соединений к одному хосту), так и со стороны сервера (каждое соединение потребляет ресурсы — при бесконечном количестве соединений сервер ляжет).
- Сетевая неэффективность. Каждое соединение — это отдельный TCP-поток. В рамках одного соединения, пока мы ждём ответа, сеть простаивает. Несколько соединений используют сеть немного эффективнее, но всё равно каждое из них простаивает в момент ожидания ответа.
Эти ограничения привели к появлению HTTP/2, где параллельные запросы в рамках одного соединения реализованы на уровне протокола (мультиплексирование).
HTTP/2
Проблема последовательных запросов в HTTP/1 привела к появлению HTTP/2 — протокола, который изначально разрабатывался Google (эксперименты начались в конце 2000-х, стандарт утверждён в 2015 году). Сегодня большинство сайтов в браузере работают уже поверх HTTP/2, часто незаметно для пользователя.
HTTP/2 не отменяет базовые понятия HTTP/1 — те же глаголы (GET, POST, …), эндпоинты, заголовки, статус-коды. Всё это осталось. Изменился способ, которым эти сообщения передаются «под капотом».
Главные изменения HTTP/2
1. Бинарный протокол
Если HTTP/1 передавал данные в виде обычного текста (с переносами строк и т. д.), то HTTP/2 — бинарный протокол. Данные упаковываются в компактный бинарный формат, который эффективнее парсить и передавать. По сути, это тот же текст, но упакованный и «нарезанный» иначе.
2. Мультиплексирование
Ключевое нововведение HTTP/2 — возможность параллельно отправлять несколько запросов в рамках одного TCP-соединения. В HTTP/1 для параллельной загрузки нескольких ресурсов приходилось открывать несколько соединений. В HTTP/2 достаточно одного соединения — запросы и ответы передаются одновременно, не дожидаясь друг друга.
Frame и Stream
В HTTP/1 существовало только одно понятие — сообщение (request или response).
Чтобы реализовать мультиплексирование, HTTP/2 вводит две новые абстракции:
- Frame (фрейм) — небольшой фрагмент, на который делится сообщение. При этом фрейм — это понятие уровня HTTP/2, не TCP.
- Stream (стрим) — пара «запрос-ответ» (один request и один response).
Именно они позволяют «нарезать» сообщения на маленькие кусочки и перемешивать их в одном соединении.
Каждое HTTP-сообщение (запрос или ответ) может быть разделено на несколько фреймов. Фреймы нумеруются и помечаются — какой фрейм к какому сообщению (стриму) относится. На стороне получателя фреймы собираются обратно в исходное сообщение.
Важно: когда говорят «стрим» в контексте HTTP/2, имеется в виду не аудио- или видеопоток, а последовательность отправки фреймов одного запроса-ответа.
Особенность HTTP/2: отправитель может не указывать заранее количество фреймов. Например, при стриминге событий, файла или аудио — отправитель может начать передавать фреймы по мере готовности, а получатель начнёт их обрабатывать, не дожидаясь всего объёма данных.
Мультиплексирование
Главное, ради чего вводились фреймы и стримы — мультиплексирование. В рамках одного TCP-соединения может существовать несколько стримов одновременно. То есть:
- Клиент может отправить несколько запросов параллельно, не дожидаясь ответа на каждый предыдущий.
- Фреймы разных стримов могут перемешиваться в произвольном порядке при отправке и получении.
- Соединение при этом простаивает гораздо меньше — пока сервер обрабатывает один запрос, по тому же соединению уже могут передаваться данные другого запроса или ответа.
Именно это решает проблему HTTP/1, где запросы строго последовательны и соединение простаивает в ожидании ответа.
Нет двунаправленности
Несмотря на все нововведения, HTTP/2 не является двунаправленным протоколом. Каждый стрим по-прежнему инициируется клиентом (запросом), а сервер может только ответить на него. Сервер не может сам инициировать новый стрим в сторону клиента. Для двунаправленного взаимодействия используются WebSocket или gRPC (с его стримингом).
Аналогия: HTTP/1 vs HTTP/2

Чтобы лучше понять разницу, можно представить себе провод:
- HTTP/1 — это провод с одной медной жилкой. Все запросы идут последовательно, друг за другом, по одному каналу.
- HTTP/2 — это провод с внешней резиновой оболочкой (само TCP-соединение) и несколькими жилками внутри. Каждая жилка — это отдельный HTTP-стрим, в рамках которого движется один запрос и один ответ. При этом данные внутри каждого стрима дополнительно нарезаны на фреймы.
Зачем делить сообщения на фреймы
Эффективное использование сети. TCP-соединение не стало быстрее или шире — пропускная способность осталась прежней. Но если мы передаём данные небольшими фрагментами (фреймами), мы можем перемешивать фреймы разных стримов в одном соединении. В результате сеть простаивает меньше: пока сервер обрабатывает один запрос, по тому же соединению уже могут идти фреймы другого запроса или ответа. Не нужно ждать, пока целиком вернётся один большой ответ, чтобы начать следующий.
Механизм стриминга. Если отправитель заранее не знает, сколько данных будет передано (например, стриминг событий, загрузка большого файла), он может начать отправлять фреймы по мере готовности первой части данных. Получатель начнёт их обрабатывать сразу, не дожидаясь полного объёма.
Конкретная логика того, как именно сообщение делится на фреймы и в каком порядке они отправляются, определена на уровне протокола HTTP/2.
Минусы HTTP/2
Поддержка инфраструктуры. Не всё сетевое оборудование и программное обеспечение на данный момент умеет корректно работать с HTTP/2. Хотя по данным мониторинга популярных ресурсов, переход уже превысил 70–80 %.
Проблема блокировки на уровне TCP. Это одна из причин, почему появился HTTP/3.
Резюме: что такое HTTP/2
- Бинарный протокол. Данные передаются не в виде текста, а в компактном бинарном формате.
- Параллельные запросы. Мультиплексирование нескольких стримов в рамках одного TCP-соединения.
- Остаётся request-response протоколом. Каждый стрим по-прежнему инициируется клиентом (запросом), сервер может только ответить. Сервер не может сам инициировать стрим в сторону клиента.
HTTP/3 (кратко)
HTTP/3 — это отдельная большая тема. Здесь отметим только ключевую идею.
В TCP есть проблема блокировки начала очереди (head-of-line blocking). Если один пакет потерялся, все последующие пакеты вынуждены ждать его повторной отправки, даже если они относятся к другому запросу. В HTTP/2 эта проблема сохраняется, потому что под ним всё ещё TCP.
Google пошёл нестандартным путём: вместо того чтобы пытаться менять TCP (что невозможно на уровне глобальной инфраструктуры), они разработали QUIC — аналог TCP, но работающий поверх UDP. А уже поверх QUIC строится HTTP/3.
История с HTTP/3 и QUIC наглядно демонстрирует: если протокол нижнего уровня (UDP) не даёт нужных гарантий, это не значит, что их нельзя получить. Вы можете реализовать свою логику поверх него — либо самостоятельно, либо используя протокол-надстройку (как QUIC поверх UDP).