Что такое заголовки в HTTP и зачем они нужны?

Что такое заголовки в HTTP и зачем они нужны?

Теория: что такое HTTP-заголовки

HTTP-заголовки (headers) — это поля метаданных внутри HTTP-запросов и HTTP-ответов, которые задают контекст и параметры обработки сообщения, не являясь самим «контентом» ресурса. Заголовки позволяют согласовать поведение клиента, сервера и промежуточных узлов (прокси, кэши, балансировщики), оставаясь отдельным механизмом от URL и тела запроса.

В современных спецификациях HTTP семантика описывается отдельно от конкретной версии транспорта (HTTP/1.1, HTTP/2, HTTP/3), но идея заголовков сохраняется: передача структурированной «служебной» информации рядом с данными. На практике в HTTP/2 и HTTP/3 заголовки кодируются иначе (двоичные фреймы и сжатие), но логически это те же поля заголовков.

Структура сообщения HTTP/1.1

В HTTP/1.1 сообщение состоит из:

  • стартовой строки (request line или status line),
  • строк заголовков (0 или более),
  • пустой строки (разделитель),
  • тела (опционально).
Запрос (пример)

GET /products?category=books HTTP/1.1
Host: shop.example
Accept: application/json
User-Agent: ExampleBrowser/1.0
Ответ (пример)

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 52
Cache-Control: max-age=60

{ "items": [ { "id": 1, "name": "..." } ] }
Некорректный разбор заголовков (например, неоднозначная обработка пробелов, переносов строк, дублирующихся полей или длины тела) способен приводить к серьёзным уязвимостям на границе прокси и серверов. Поэтому строгая валидация синтаксиса заголовков и единые правила обработки являются важной частью безопасной Web-разработки.

Синтаксис заголовков

Базовая форма заголовка — field-name: field-value, где:

  • field-name — имя поля (например, Content-Type, Accept, Authorization),
  • field-value — значение (например, application/json).

Имя поля заголовка нечувствительно к регистру, то есть Content-Type и content-type эквивалентны по смыслу, хотя в реальных системах иногда встречаются ошибки из-за неверных предположений в коде. Важно различать: заголовки — это не часть URL и не часть тела, а отдельный слой управления и метаданных.

Зачем нужны заголовки

Заголовки решают задачи, которые неудобно или неправильно решать через URL или тело:

  • Согласование представления данных: какие форматы умеет клиент (Accept), в каком формате отправлены данные (Content-Type), в какой кодировке и на каком языке.
  • Управление кэшированием и повторным использованием ответов: как долго ответ можно хранить, при каких условиях он считается свежим.
  • Аутентификация и авторизация: как именно клиент доказывает право доступа (Authorization), как сервер инициирует проверку (например, WWW-Authenticate).
  • Диагностика и маршрутизация: информация о целевом хосте, цепочке прокси, ограничениях, предпочтениях и возможностях клиента.

С практической точки зрения заголовки — это «контракт поведения» между сторонами: один и тот же URL может вернуть разные представления ресурса в зависимости от заголовков, а один и тот же ответ может по-разному кэшироваться и использоваться в зависимости от политики, заданной в заголовках.

Категории и примеры заголовков

Ниже приведена удобная группировка (не единственно возможная), чтобы быстрее ориентироваться.

Таблица: задачи и примеры полей

ЗадачаПримеры заголовковЧто меняется в поведении
Формат данныхContent-Type, Accept, Accept-LanguageКак интерпретировать тело и что предпочитает клиент
КэшированиеCache-Control, ETag, If-None-MatchМожно ли хранить ответ и можно ли получить 304 вместо тела
АутентификацияAuthorization, WWW-AuthenticateКак подтверждаются права доступа
Передача телаContent-Length, Transfer-EncodingКак определить границы тела и способ передачи
Безопасность/политикиStrict-Transport-Security, Content-Security-PolicyКак браузер должен ограничивать опасное поведение
Информация о клиентеUser-AgentКак сервер может адаптировать ответ (осторожно)
Заголовки условно делятся на заголовки запроса, заголовки ответа и «общие» для обоих направлений, но в повседневной разработке важнее понимать их назначение и область действия, чем формальную классификацию.

Практика: типовые сценарии

Согласование формата (content negotiation)

Клиент может объявить, что предпочитает application/json, а сервер обязан явно указать, какой формат реально отправлен.

Запрос
GET /api/items HTTP/1.1
Host: api.example
Accept: application/json

Ответ
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 18

{ "items": [] }

Кэширование с ETag и 304

ETag — идентификатор версии ресурса; клиент может переспросить «изменилось ли», не скачивая тело заново.

Первый ответ
HTTP/1.1 200 OK
Content-Type: text/css
ETag: "v1"
Cache-Control: max-age=0
Content-Length: 12

body{...}

Повторный запрос
GET /styles.css HTTP/1.1
Host: site.example
If-None-Match: "v1"

Ответ, если не изменилось
HTTP/1.1 304 Not Modified
ETag: "v1"

Аутентификация через Bearer-токен

В API часто передаются учетные данные через Authorization: Bearer ....

GET /api/profile HTTP/1.1
Host: api.example
Accept: application/json
Authorization: Bearer eyJhbGciOi...

Пример в JavaScript (Fetch API)

Заголовки запроса задаются в headers, а значения ответных заголовков читаются через response.headers.get(...).

const response = await fetch("https://api.example/items", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Accept": "application/json",
    "Authorization": "Bearer <token>"
  },
  body: JSON.stringify({ name: "item" })
});

const contentType = response.headers.get("content-type");
const data = await response.json();

Частые ошибки и как их избегать

  • Путаница заголовков с query-параметрами: параметры в URL обычно описывают выбор ресурса/варианта запроса, заголовки — правила и контекст обработки сообщения.
  • Несоответствие Content-Type и реального тела: если тело — JSON, должен быть указан Content-Type: application/json, иначе сервер/клиент может неверно распарсить данные.
  • Некорректная работа с Content-Length и прокси: при ручной сборке HTTP-сообщений и нестандартных прокси-схемах особенно важно исключить двусмысленность границ тела.
  • Слепое доверие клиентским заголовкам: User-Agent, «псевдо IP» в заголовках и любые «самоописания» клиента могут подделываться; для безопасности следует опираться на проверяемые механизмы.
В заголовках нередко оказываются чувствительные данные (токены, cookies). Их утечка в логи, аналитические системы или сторонние прокси может приводить к компрометации аккаунтов, поэтому необходимо аккуратно настраивать логирование и маскирование секретов.

Итого: HTTP-заголовки — это поля имя: значение в запросах и ответах, которые передают метаданные и управляют обработкой сообщения (формат, кэш, аутентификация, политики безопасности и прочее). Правильное понимание заголовков помогает отличать «данные ресурса» (тело) от «правил и контекста» (заголовки) и снижает риск ошибок в производительности и безопасности.