Что находится внутри HTTP-ответа?
Каждый раз, когда ваш браузер загружает страницу или ваш JavaScript вызывает fetch(), сервер отправляет обратно HTTP-ответ. Вы видите результат — отрендеренную страницу, JSON-данные, сообщение об ошибке — но сам ответ содержит больше структуры, чем большинство разработчиков осознанно об этом думают. Понимание этой структуры дает вам более четкую мысленную модель при отладке в DevTools или обработке ответов в коде.
HTTP-ответ состоит из трех частей: строки состояния, заголовков и необязательного тела.
Ключевые моменты
- Каждый HTTP-ответ состоит из трех частей: строки состояния (или псевдозаголовка
:statusв HTTP/2 и HTTP/3), заголовков и необязательного тела. - Коды состояния группируются по первой цифре — 2xx для успеха, 3xx для перенаправления, 4xx для клиентских ошибок и 5xx для серверных ошибок.
- Заголовки ответа управляют кешированием, безопасностью, cookies и интерпретацией контента — они сообщают браузеру как обрабатывать полезную нагрузку, а не только что это такое.
- Не все заголовки ответа доступны для frontend JavaScript в кросс-доменных запросах. Серверы должны использовать
Access-Control-Expose-Headers, чтобы разрешить доступ за пределами стандартного безопасного набора.
Анатомия HTTP-ответа: статус, заголовки, тело
Строка состояния
В HTTP/1.1 ответ начинается с одной строки состояния:
HTTP/1.1 200 OK
Эта строка содержит версию протокола, трехзначный код состояния и человекочитаемую фразу-причину. Фраза-причина носит только информационный характер — браузеры и клиенты фактически реагируют на код состояния.
Коды состояния HTTP группируются по первой цифре:
| Диапазон | Значение |
|---|---|
| 1xx | Информационные (запрос получен, обработка продолжается) |
| 2xx | Успех (200 OK, 201 Created, 204 No Content) |
| 3xx | Перенаправление (301 Moved Permanently, 304 Not Modified) |
| 4xx | Ошибка клиента (400 Bad Request, 401 Unauthorized, 404 Not Found) |
| 5xx | Ошибка сервера (500 Internal Server Error, 503 Service Unavailable) |
Примечание о HTTP/2 и HTTP/3: Текстовая строка состояния выше специфична для формата передачи HTTP/1.1. В HTTP/2 и HTTP/3 строки состояния нет. Вместо этого статус передается через псевдозаголовок :status (например, :status: 200). Семантика идентична — код состояния означает то же самое — но представление отличается. DevTools нормализует представление, поэтому вы все равно увидите привычный код состояния независимо от версии протокола.
Заголовки HTTP-ответа: что они на самом деле делают
Заголовки ответа — это метаданные. Они сообщают браузеру как обрабатывать ответ, а не что представляет собой контент. Каждый заголовок — это нечувствительное к регистру имя, за которым следует двоеточие и значение.
Вот категории, с которыми вы будете сталкиваться чаще всего:
Метаданные контента
Content-Type: application/json; charset=utf-8— сообщает браузеру, в каком формате находится тело и как его декодировать.Content-Length: 1024— размер тела в байтах.
Кеширование
Cache-Control: max-age=3600, public— указывает браузеру и CDN, как долго кешировать ответ.ETag: "abc123"— отпечаток ресурса, используемый для условных запросов. Если ресурс не изменился, сервер возвращает304 Not Modifiedвместо полного тела.
Безопасность
Content-Security-Policy— ограничивает источники, из которых браузер может загружать скрипты, стили и другие ресурсы.Strict-Transport-Security— указывает браузеру подключаться только через HTTPS в течение указанного времени.
Cookies
Set-Cookie: session=xyz; HttpOnly; Secure— указывает браузеру сохранить cookie. Один ответ может включать несколько заголовковSet-Cookie, по одному на каждый cookie.
Одно важное ограничение: не все заголовки ответа доступны для frontend JavaScript. По умолчанию Fetch API предоставляет доступ только к небольшому набору “безопасных” заголовков из кросс-доменных ответов. Серверы должны явно перечислить дополнительные заголовки в Access-Control-Expose-Headers, чтобы ваш JavaScript мог их прочитать.
Тело ответа
Тело — это фактическая полезная нагрузка — HTML, JSON, изображение, файл. Не каждый ответ имеет тело. Ответ 204 No Content или 304 Not Modified намеренно опускает тело. В этих случаях сам код состояния является сообщением.
Заголовок Content-Type сообщает браузеру, как интерпретировать то, что приходит в теле.
Discover how at OpenReplay.com.
Менее распространенные возможности, о которых стоит знать
HTTP-ответы также могут включать информационные ответы, такие как 103 Early Hints, который позволяет серверам предлагать ресурсы для предварительной загрузки до прибытия основного ответа. Трейлеры — заголовки, отправляемые после тела — существуют в HTTP/1.1 (с chunked transfer encoding) и в HTTP/2 и HTTP/3 как завершающие заголовки, но редко встречаются в повседневной frontend-разработке. О них стоит знать, но вы не будете часто видеть их в DevTools.
Заключение
Думайте об HTTP-ответе как о конверте. Код состояния сообщает вам, была ли доставка успешной. Заголовки — это инструкции снаружи — обращаться осторожно, хранить в холодильнике после открытия, срок годности 24 часа. Тело — это то, что внутри. Когда что-то ломается, сначала проверьте код состояния, затем заголовки — они обычно точно говорят вам, что пошло не так и что делать дальше.
Часто задаваемые вопросы
Content-Length указывает точный размер тела ответа в байтах. Transfer-Encoding, обычно установленный в chunked, означает, что тело отправляется частями без заранее определенного общего размера. В HTTP/1.1 ответ использует либо одно, либо другое. Chunked encoding распространен для динамически генерируемого контента, когда сервер не знает конечный размер заранее.
Для кросс-доменных запросов Fetch API по умолчанию предоставляет доступ только к ограниченному набору заголовков ответа, разрешенных CORS. К ним относятся Cache-Control, Content-Language, Content-Type, Expires, Last-Modified и Pragma. Чтобы получить доступ к любому другому заголовку из JavaScript, сервер должен включить его в заголовок ответа Access-Control-Expose-Headers.
Используйте 204 No Content, когда сервер успешно обрабатывает запрос, но не имеет тела для возврата. Это распространено для операций DELETE или отправки форм, когда клиенту не нужны обновленные данные в ответе. 200 OK более уместен, когда вы хотите отправить подтверждающую полезную нагрузку или обновленный ресурс обратно клиенту.
Откройте DevTools с помощью F12 или Ctrl+Shift+I, перейдите на вкладку Network и щелкните любой запрос в списке. Панель Headers показывает как заголовки запроса, так и ответа. Вы также можете фильтровать по типу запроса и искать конкретные имена заголовков. Вкладка Response показывает необработанное содержимое тела, возвращенное сервером.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.