Каждый раз, когда пользователь интернета открывает сайт, его браузер отправляет на сервер HTTP-запрос, а сервер возвращает HTTP-ответ. Этот обмен происходит незаметно для человека, но именно от него зависит, увидит ли посетитель нужную страницу, получит ли сообщение об ошибке или его вовсе перенаправят на другой адрес. Разберемся, из чего состоит HTTP-запрос, какие методы существуют, что такое строка статуса и какие коды состояния встречаются чаще всего.
Что такое HTTP-запрос
HTTP(HyperText Transfer Protocol) – протокол передачи данных, на котором строится работа веб-сайтов. Он определяет правила, по которым клиент (браузер, мобильное приложение, скрипт) и сервер обмениваются информацией.
Работает это по модели «запрос – ответ»:
- Клиент формирует HTTP-запрос и отправляет его на сервер.
- Сервер обрабатывает запрос и возвращает HTTP-ответ.
- Клиент получает ответ и отображает результат – например, страницу сайта.
HTTP – протокол без сохранения состояния (stateless). Каждый запрос обрабатывается независимо, сервер не хранит историю предыдущих обращений клиента. Для сохранения данных между запросами используются дополнительные механизмы – cookies, сессии, токены.
Структура HTTP-запроса
Любой HTTP-запрос состоит из четырех частей:
- Стартовая строка (request line) – метод, путь к ресурсу и версия протокола.
- Заголовки (headers) – метаданные запроса.
- Пустая строка – разделитель между заголовками и телом.
- Тело запроса (body) – необязательная часть с данными.
Стартовая строка
Выглядит следующим образом:
GET /catalog/tovar-123 HTTP/1.1Здесь:
GET– метод запроса;/catalog/tovar-123– путь к запрашиваемому ресурсу;HTTP/1.1– версия протокола.
Путь может включать и строку запроса (query string) – дополнительные параметры HTTP-запроса после знака ?. Например:
GET /catalog/tovar-123?color=red&size=42 HTTP/1.1Здесь color=red&size=42 – параметры, которые передаются серверу вместе с путем. Они часто используются для фильтрации, сортировки или пагинации. В отличие от тела запроса, query-параметры видны в адресной строке браузера, в истории браузера и в логах сервера – поэтому передавать в них пароли, токены или другие чувствительные данные не стоит.
Заголовки
Заголовки передают дополнительную информацию о запросе: какой браузер используется, какой формат ответа ожидается, авторизационные данные и так далее. Например:
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html
Cookie: session_id=abc123
Content-Type: application/jsonКаждый заголовок – это пара «имя: значение», записанная на отдельной строке.
Тело запроса
Тело есть не у всех запросов. Например, у GET оно обычно отсутствует, а у POST или PUT в нем передаются данные – содержимое формы, JSON-объект, файл. Пример тела запроса в формате JSON:
{
"name": "Ivan",
"email": "ivan@example.com"
}Полный пример HTTP-запроса
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 45
{"name": "Ivan", "email": "ivan@example.com"}Методы HTTP-запроса
Метод сообщает серверу, какое действие нужно выполнить с ресурсом.
Самые распространенные виды методов HTTP-запроса:
GET– получение данных ресурса. Не изменяет состояние сервера.POST– отправка данных на сервер для создания нового ресурса или запуска обработки.PUT– полная замена существующего ресурса переданными данными.PATCH– частичное обновление ресурса.DELETE– удаление указанного ресурса.HEAD– аналогGET, но сервер возвращает только заголовки, без тела ответа.OPTIONS– запрос списка методов и возможностей, поддерживаемых ресурсом или сервером.TRACE– возврат полученного запроса «как есть». Используется для диагностики.CONNECT– установка туннельного соединения, обычно для работы через прокси по HTTPS.
Идемпотентность и безопасность методов
При работе с методами важны два понятия:
- Безопасные методы не изменяют состояние сервера – это, например,
GET,HEAD,OPTIONS. Они только читают данные. - Идемпотентные методы – при многократном повторном выполнении дают тот же результат, что и при однократном. К ним относятся
GET,PUT,DELETE,HEAD,OPTIONSиTRACE. А вотPOSTиPATCHидемпотентными не являются: повторная отправка одного и того жеPOST-запроса может, например, создать второй одинаковый заказ.
Это различие важно учитывать при разработке API и настройке кэширования. Кэшировать без риска получить устаревшие или неверные данные можно только безопасные методы – GET и HEAD, поскольку они не меняют состояние ресурса. А вот повторять запрос при сбое сети без опасений «сломать» что-то на сервере можно, если метод идемпотентен – это GET, PUT, DELETE, HEAD, OPTIONS и TRACE.
PUT и DELETE идемпотентны, но их, в отличие от GET и HEAD, не кэшируют. Они изменяют состояние сервера, а не только читают данные. POST и PATCH не обладают ни тем, ни другим свойством, поэтому их повторную отправку нужно обрабатывать отдельно – например, защитой от двойного клика при оформлении заказа.Структура HTTP-ответа
В ответ на запрос сервер отправляет HTTP-ответ, который по структуре похож на запрос, но вместо стартовой строки содержит строку статуса:
- Строка статуса (status line).
- Заголовки ответа.
- Пустая строка.
- Тело ответа – HTML-страница, JSON, файл и так далее.
Строка статуса
Строка статуса – первая строка HTTP-ответа. Она сообщает клиенту, как сервер обработал запрос. Формат строки:
HTTP/1.1 200 OKСтрока состоит из трех частей:
- Версия протокола – например,
HTTP/1.1. - Код состояния – трехзначное число, например,
200. - Пояснительная фраза (reason phrase) – текстовое описание кода, например,
OK. Эта часть носит справочный характер и не влияет на обработку ответа.
Пример полного ответа сервера:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1256
<!DOCTYPE html>
<html>...</html>Некоторые заголовки характерны именно для ответа и не встречаются в запросах. Например, при редиректе сервер указывает новый адрес в заголовке Location:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-pageА чтобы установить cookie на стороне клиента, сервер использует Set-Cookie:
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; HttpOnly; SecureИменно этот session_id, установленный сервером, клиент затем передает обратно в заголовке Cookie в следующих запросах – том самом, что был показан в примере заголовков запроса выше.
Коды состояния HTTP
Коды состояния делятся на пять классов в зависимости от первой цифры HTTP-запроса.
1xx – информационные
Означают, что сервер принял запрос и продолжает его обработку.
100 Continue– сервер получил начальную часть запроса и клиент может продолжать отправку.101 Switching Protocols– сервер соглашается сменить протокол по просьбе клиента (например, при переходе на WebSocket).103 Early Hints– предварительные заголовки, которые сервер отправляет до основного ответа, чтобы браузер мог заранее начать загрузку связанных ресурсов.
2xx – успешные
Запрос был получен, понят и успешно обработан.
200 OK– запрос выполнен успешно.201 Created– новый ресурс успешно создан (обычно в ответ наPOSTилиPUT).202 Accepted– запрос принят к обработке, но она еще не завершена.204 No Content– запрос выполнен успешно, но тело ответа отсутствует.
3xx – перенаправления
Сообщают, что для завершения запроса нужны дополнительные действия, обычно переход по другому адресу.
301 Moved Permanently– ресурс перемещен на новый адрес навсегда.302 Found– временное перенаправление. По стандарту при таком переходе метод и тело запроса должны сохраняться, но на практике большинство браузеров при301и302меняют исходный метод наGET– это историческая особенность, закрепившаяся в поведении браузеров еще с ранних версий HTTP. Именно поэтому позже появились коды307и308.303 See Other– явное указание получить ресурс методомGETпо другому адресу. Классический паттерн – редирект после успешной обработкиPOST-запроса (например, после отправки формы или оформления заказа), чтобы обновление страницы браузером не приводило к повторной отправке формы.304 Not Modified– ресурс не изменился с последнего запроса, можно использовать кэшированную версию.307 Temporary Redirectи308 Permanent Redirect– аналоги302и301, но гарантированно сохраняющие исходный метод и тело запроса при переходе.
Редиректы на виртуальном хостинге настраиваются через файл .htaccess, поможет их настроить наша статья.
4xx – ошибки клиента
Этот код указывают, что HTTP-запрос содержит ошибку или не может быть обработан по вине клиента.
400 Bad Request– сервер не понял запрос из-за некорректного синтаксиса.401 Unauthorized– требуется аутентификация.403 Forbidden– доступ к ресурсу запрещен, даже если клиент аутентифицирован, то есть сервер точно знает, кто он. Разница между401и403– это и есть разница между аутентификацией и авторизацией:401означает «сначала представьтесь», а403– «вы представились, но прав на это действие всё равно нет». Разобраться в причине ошибки, а также исправить ее поможет наша статья.404 Not Found– запрашиваемый ресурс не найден.405 Method Not Allowed– метод запроса не поддерживается для данного ресурса.429 Too Many Requests– превышен лимит запросов за определенный период.
5xx – ошибки сервера
Означают, что сервер получил корректный запрос, но не смог его обработать.
500 Internal Server Error– общая ошибка сервера при выполнении HTTP-запроса, без уточнения причины.502 Bad Gateway– сервер, выступающий шлюзом или прокси, получил некорректный ответ от вышестоящего сервера.503 Service Unavailable– сервер временно не может обработать запрос, например, из-за перегрузки или технических работ.504 Gateway Timeout– сервер-шлюз не дождался, не получил ответы HTTP-запросов от вышестоящего сервера.
HTTP/1.1, HTTP/2, HTTP/3 и HTTPS
Всё, что описано выше, справедливо для HTTP/1.1 – самой распространенной версии при объяснении протокола. Но на большинстве современных сайтов данные передаются по HTTP/2 или HTTP/3: они используют бинарный формат вместо текстового, умеют передавать несколько запросов в рамках одного соединения и работают быстрее, особенно на медленных или нестабильных сетях. При этом методы, заголовки и коды состояния HTTP-запроса остаются теми же – всё, что рассказано в статье про GET, POST, коды 200, 404 или 500, одинаково справедливо для всех версий протокола, меняется только формат передачи данных.
Отдельно стоит уточнить про HTTPS: это не другой протокол, а тот же HTTP, передаваемый поверх защищенного соединения TLS. Структура запросов и ответов не меняется, но трафик между клиентом и сервером шифруется. В свою очередь, при работе через незащищенное HTTP-соединение запросы и ответы передаются без шифрования.
Как посмотреть HTTP-запросы и ответы на практике
Изучить реальные запросы можно несколькими способами:
- Инструменты разработчика в браузере – вкладка «Сеть» (Network) в Chrome, Firefox или другом браузере показывает все запросы страницы, их заголовки, коды ответов и время выполнения.
- Утилита curl – позволяет отправлять запросы из терминала и видеть полный ответ сервера. Например, команда
curl -I example.comвыведет только заголовки ответа, включая строку статуса. Более полезна для изучения структуры обмена командаcurl -v example.com– она показывает и сам отправленный запрос, и полный ответ сервера, включая все заголовки. - Отдельные приложения для тестирования API, такие как Postman или Insomnia – удобны для ручного составления и отправки запросов разных типов.
Заключение
HTTP-запрос и HTTP-ответ – это не абстрактная теория, а то, с чем ежедневно сталкивается каждый, кто работает с сайтом или API. Разобравшись в кодах состояния, можно быстро понять, где искать причину проблемы:
- Код начинается с
4хх– проблема на стороне клиента: неверный запрос, отсутствие авторизации, обращение к несуществующему адресу. Стоит проверить сам запрос – URL, заголовки, тело, права доступа. - Код начинается с
5хх– проблема на стороне сервера: ошибка в коде приложения, недоступность базы данных, перегрузка или сбой в работе сервера. Здесь уже нужно смотреть логи сервера. Разобраться в причинах ошибок, а также исправить их поможет наша статья. - Код начинается с
3хх– это не ошибка HTTP-запроса, а часть нормальной работы сайта (редирект), но если редиректов оказывается больше одного-двух подряд или они зацикливаются, это повод проверить настройки.
Умение быстро определить класс кода состояния экономит время при диагностике: вы сразу понимаете, где может быть проблема.
Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить работу HTTP-запросов или наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.