Заголовки HTTP
ProQuality CommunityМы продолжаем серию статей про API. В предыдущих статьях:
- Что такое API
- Структура запросов и ответов web API
- Методы и для чего используются в HTTP.
- Виды аутентификации в REST API
Сегодня мы рассмотрим заголовки в HTTP запросах и ответах.

Заголовки HTTP служат для передачи дополнительной информации с запросом или ответом между сервером и клиентом. Заголовок HTTP состоит из его имени без учета регистра, и значения, разделённых между собой двоеточием. Имена заголовков нечувствительны к регистру.
Основной набор заголовков стандартизирован Инженерным Советом Интернета (англ. Internet Engineering Task Force, IETF). Постоянный реестр полей заголовков и репозиторий временных регистраций поддерживаются IANA. Имена дополнительных полей и допустимые значения могут определяться каждым приложением.
Кроме стандартизированных заголовков разработчики могут создавать собственные. Эти заголовки используются для передачи дополнительной информации, которая имеет отношение к веб-разработчикам или для поиска неполадок.
Нестандартные поля заголовка обычно помечались префиксом “X-“ перед именем поля, но это соглашение было объявлено устаревшим в июне 2012 года из-за неудобств, которые оно вызвало, когда нестандартные поля стали стандартными.
Общий формат заголовков
Поля заголовка передаются после строки запроса (в случае сообщения HTTP с запросом) или строки ответа (в случае сообщения HTTP ответа), которая является первой строкой сообщения. Поля заголовка представляют собой пары ключ-значение, разделенные двоеточиями, в формате строки с открытым текстом, заканчивающиеся последовательностью символов возврата каретки (CR) и перевода строки (LF). Конец раздела заголовка обозначается пустой строкой поля, что приводит к передаче двух последовательных пар CR-LF.
Название заголовка должно состоять как минимум из одного печатного символа. Название не чувствительно к регистру.
Значение заголовка может содержать любые символы ASCII кроме перевода строки и возврата каретки.
Предусматривается размещение значения на нескольких строках (перенос строки). Для указания переноса в начале следующей строки должен находиться хотя бы один пробельный символ.
Заголовки с одинаковыми названиями параметров, но разными значениями могут объединяться в один, только если значение поля представляет из себя разделённый запятыми список. Во всех остальных случаях значения более дальних заголовков должны перекрывать предыдущие. Поэтому прокси-сервера не должны менять порядок следования заголовков в сообщении. При этом порядок элементов списка обычно значения не имеет.
Заголовки можно разделить на типы по контексту:
- Заголовки запроса содержат дополнительную информацию о ресурсе, который нужно получить, или о клиенте, запрашивающем ресурс.
- Заголовки ответа содержат дополнительную информацию об ответе, например его местонахождение или предоставивший его сервер.
- Заголовки представления содержат информацию о теле ресурса, например о его MIME-типе или применяемом кодировании / сжатии.
- Заголовки полезной нагрузки содержат независимую от представления информацию о данных полезной нагрузки, включая длину содержимого и кодировку, используемую для транспорта.
Заголовки запроса используются для предоставления дополнительной информации о контексте запроса, для того чтобы сервер правильно обработал запрос. Например заголовок Accept-* указывает допустимые и предпочитаемые форматы для ответа. Также к заголовкам запроса можно отнести те, которые используются для аутентификации, контроля кэша, для получения информации о пользовательском агенте или реферерре.
Не все заголовки, которые могут появляться в запросе, в спецификации называются заголовками запроса. Например, заголовок Content-Type называется заголовком представления.
К заголовкам ответа относятся заголовки которые не несут информации о контенте сообщения, например Age, Location, Server используются для предоставления более детальной информации об ответе.
В обсуждениях все заголовки в ответе обычно относят к заголовкам ответа, хотя это не верно. Например, заголовок Content-Type относится к заголовкам представления.
Заголовки представления описывают определённое представление ресурса отправленного в теле сообщения.
Представления – это разные версии одного и того же ресурса, которые могут быть отправлены в теле сообщения. Например, одни и те же данные можно представить в виде XML или JSON, и этот ресурс затем может быть закодирован в один или несколько сжатых форматов для отправки. Клиент указывает форматы, которые они предпочитают используя заголовки Accept- *, а заголовки представления сообщают клиенту формат представления, которое они фактически получили.
Заголовки представления могут присутствовать как в сообщениях запроса и ответа. Если они отправлены как ответ на запрос HEAD, они описывают содержимое тела, которое было бы отправлено, если бы ресурс действительно был запрошен.
К заголовкам представления относятся: Content-Type, Content-Encoding, Content-Language, and Content-Location.
Заголовки полезной нагрузки включают в себя такую информацию, как длина полезной нагрузки сообщения, какая часть ресурса переносится в этой полезной нагрузке (для сообщения, состоящего из нескольких частей), любое кодирование, применяемое для транспорта, проверки целостности сообщения и т. д. Заголовки полезной нагрузки могут присутствовать как в HTTP сообщения запроса и ответа (т. е. в любом сообщении, которое несет данные полезной нагрузки). К заголовкам полезной нагрузки относятся: Content-Length, Content-Range, Trailer и Transfer-Encoding.
Ниже представлены примеры заголовков в запросе и ответе. Попробуйте разделить эти заголовки на типы по контексту 😊.
Запрос:
GET /home.html HTTP/1.1 Host: developer.mozilla.org User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Referer: https://developer.mozilla.org/testpage.html Connection: keep-alive Upgrade-Insecure-Requests: 1 If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a" Cache-Control: max-age=0
Ответ:
200 OK Access-Control-Allow-Origin: * Connection: Keep-Alive Content-Encoding: gzip Content-Type: text/html; charset=utf-8 Date: Mon, 18 Jul 2016 16:06:00 GMT Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a" Keep-Alive: timeout=5, max=997 Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT Server: Apache Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure Transfer-Encoding: chunked Vary: Cookie, Accept-Encoding X-Backend-Server: developer2.webapp.scl3.mozilla.com X-Cache-Info: not cacheable; meta data too large X-kuma-revision: 1085259 x-frame-options: DENY
Заголовки также можно сгруппировать в зависимости от того, как их обрабатывают прокси:
- Connection. Этот заголовок определяет, остается ли сетевое соединение активным после завершения текущей транзакции. Если в запросе отправлено значение keep-alive, то соединение остаётся и не завершается, позволяя выполнять последующие запросы на тот же сервер.
- Keep-Alive – позволяет отправителю подсказывать, как можно использовать соединение для установки тайм-аута и максимального кол-ва запросов. Параметры соединения передаются в виде пар=значение, разделённых точкой с запятой.
- Proxy-Authenticate – заголовок ответа, определяющий метод аутентификации, который должен быть использован для получения доступа к ресурсу за прокси-сервером. Аутентифицированный запрос на прокси-сервер позволяет проходить запросу дальше.
- Proxy-Authorization – заголовок запроса, содержащий реквизиты для аутентификации агента на прокси сервере, обычно после того, как сервер ответил статусом 407 Proxy Authentication Required и заголовком Proxy-Authenticate.
- TE – заголовок запроса указывающий кодировки ответа, которые агент готов принять. Неформально его называют Accept-Transfer-Encoding, что лучше говорит о его назначении.
- Trailer – этот заголовок позволяет отправителю включать дополнительные поля в конце фрагментированных сообщений, чтобы предоставить метаданные, которые могут динамически генерироваться при отправке тела сообщения, например проверка целостности сообщения, цифровая подпись или статус постобработки.
- Transfer-Encoding определяет форму кодирования, используемую для безопасной передачи тела полезной нагрузки пользователю. Transfer-Encoding это “hop-by-hop” заголовок который применяется к сообщению между двумя узлами, а не к самому ресурсу. Каждый сегмент многоузлового соединения может использовать разные значения Transfer-Encoding. Если вы хотите сжать данные по всему соединению, используйте вместо этого сквозной заголовок Content-Encoding.
- Upgrade – заголовок обновления (только в HTTP 1.0) может использоваться клиентами, чтобы предложить серверу переключиться на один (или несколько) из перечисленных протоколов в порядке убывания предпочтений. Например, клиент может отправить запрос GET со списком предпочтительных протоколов для переключения.
- End-to-end заголовки. Эти заголовки должны быть переданы конечному получателю сообщения: серверу для запроса или клиенту для ответа. Промежуточные прокси-серверы должны повторно передавать эти заголовки без изменений, а кеши должны их хранить.
- Hop-by-hop заголовки ("шаг за шагом"). Эти заголовки имеют смысл только для одного соединения транспортного уровня и не должны повторно передаваться прокси-серверами или кэшироваться. Обратите внимание, что с помощью заголовка Connection можно установить только заголовки "hop-by-hop ".
Теперь можно вернуться к примерам запроса и ответа, и найти заголовки которые относятся к разным группам в зависимости от того, как их обрабатывает прокси 😊.
Более подробную информацию по каждому заголовку можно найти на сайте developer.mozilla или в Wikipedia.