Согласование содержимого
Согласование содержимого
В HTTP согласование содержимого — это механизм, который позволяет предоставлять разные представления ресурса по одному URI, чтобы агент пользователя мог указать, какое представление лучше всего подходит пользователю (например, язык документа, формат изображения или способ кодирования содержимого).
Примечание: Некоторые недостатки согласования содержимого HTTP перечислены на странице вики WHATWG. HTML предлагает альтернативы согласованию содержимого, например с помощью элемента <source>.
Принципы согласования содержимого
Конкретный документ называется ресурсом. Когда клиенту нужно получить ресурс, он отправляет запрос по URL. Сервер использует этот URL, чтобы выбрать один из доступных вариантов — каждый вариант называется представлением — и возвращает клиенту конкретное представление. У ресурса в целом, как и у каждого из его представлений, есть собственный URL. Согласование содержимого определяет, как выбирается конкретное представление при обращении к ресурсу. Существует несколько способов согласования между клиентом и сервером.
Наиболее подходящее представление определяется одним из двух механизмов:
- Специальные заголовки HTTP, отправляемые клиентом (согласование по инициативе сервера или проактивное согласование). Это стандартный способ согласования для определённого типа ресурса.
- Коды
300(Multiple Choices, несколько вариантов),406(Not Acceptable, неприемлемо) и415(Unsupported Media Type, неподдерживаемый тип медиа) из ответов HTTP, отправляемые сервером (согласование по инициативе агента или реактивное согласование) и используемые как резервные механизмы.
За прошедшие годы предлагались и другие варианты согласования содержимого, например прозрачное согласование содержимого и заголовок Alternates. Они не получили распространения и были заброшены.
Согласование содержимого по инициативе сервера
При согласовании содержимого по инициативе сервера, или проактивном согласовании содержимого, браузер (или другой тип агента пользователя) отправляет вместе с URL несколько заголовков HTTP. Эти заголовки описывают предпочтения пользователя. Сервер использует их как подсказки, а внутренний алгоритм выбирает наиболее подходящее содержимое для отправки клиенту. Если сервер не может предоставить подходящий ресурс, он может ответить кодом 406 (Not Acceptable, неприемлемо) или 415 (Unsupported Media Type, неподдерживаемый тип медиа) и указать поддерживаемые типы медиа в заголовках (например, использовать Accept-Post или Accept-Patch соответственно для запросов POST и PATCH). Алгоритм зависит от сервера и не определён стандартом. См. алгоритм согласования Apache.
Стандарт HTTP/1.1 определяет список стандартных заголовков, запускающих согласование по инициативе сервера (например, Accept, Accept-Encoding и Accept-Language). Хотя User-Agent в этот список не входит, его также иногда используют для отправки конкретного представления запрошенного ресурса. Однако это не всегда считается хорошей практикой. Сервер использует заголовок Vary, чтобы указать, какие заголовки он фактически использовал для согласования содержимого (точнее, соответствующие заголовки запроса), чтобы кеши могли работать оптимально.
Помимо этого, существует экспериментальное предложение добавить в список доступных заголовков новые заголовки, называемые подсказками клиента. Подсказки клиента сообщают, на каком типе устройства работает агент пользователя (например, на настольном компьютере или мобильном устройстве).
Хотя согласование содержимого по инициативе сервера — самый распространённый способ выбрать конкретное представление ресурса, у него есть несколько недостатков:
- Сервер не обладает полными сведениями о браузере. Даже с расширением Client Hints ему неизвестны все возможности браузера. В отличие от реактивного согласования содержимого, при котором выбор делает клиент, выбор сервера всегда в какой-то степени произволен.
- Данные от клиента довольно объёмны (сжатие заголовков HTTP/2 смягчает эту проблему) и создают риск для конфиденциальности (снятие цифрового отпечатка HTTP).
- Поскольку для заданного ресурса отправляется несколько представлений, общие кеши работают менее эффективно, а реализация серверов становится сложнее.
Заголовок Accept
Заголовок Accept содержит список MIME-типов медиа-ресурсов, которые агент готов обрабатывать. Это разделённый запятыми список MIME-типов, каждый из которых сопровождается коэффициентом качества — параметром, указывающим относительную степень предпочтения для разных MIME-типов.
Значение заголовка Accept задаётся браузером или другим агентом пользователя и может меняться в зависимости от контекста: например, при загрузке HTML-страницы, изображения, видео или скрипта. Оно различается при загрузке документа, адрес которого введён в адресную строку, и элемента, связанного с помощью элемента <img>, <video> или <audio>. Браузеры могут использовать значение заголовка, которое считают наиболее подходящим; доступен полный список значений по умолчанию для распространённых браузеров.
Заголовок Accept-CH
Примечание: Это часть экспериментальной технологии под названием Client Hints. Первоначальная поддержка появилась в Chrome 46 и более поздних версиях. Значение Device-Memory поддерживается в Chrome 61 и более поздних версиях.
Экспериментальный заголовок Accept-CH содержит данные о конфигурации, которые сервер может использовать для выбора подходящего ответа. Примеры допустимых значений:
| Значение | Описание |
|---|---|
Sec-CH-Device-Memory | Указывает приблизительный объём оперативной памяти устройства. Это значение является приближённым: оно получается округлением до ближайшей степени числа 2 и делением результата на 1024. Например, 512 мегабайт будут представлены как 0.5. |
Sec-CH-Viewport-Width | Указывает ширину области просмотра макета в пикселях CSS. |
Sec-CH-Width | Указывает ширину ресурса в физических пикселях (то есть исходный размер изображения). |
Заголовок Accept-Encoding
Заголовок Accept-Encoding определяет допустимые способы кодирования содержимого (поддерживаемые методы сжатия). Значение представляет собой список с коэффициентами q (например, br, gzip;q=0.8), указывающими приоритет способов кодирования. Значение по умолчанию identity имеет наименьший приоритет (если не указано иное).
Сжатие сообщений HTTP — один из важнейших способов повысить производительность веб-сайта. Оно уменьшает объём передаваемых данных и позволяет эффективнее использовать доступную пропускную способность. Браузеры всегда отправляют этот заголовок, а сервер следует настроить на использование сжатия.
Заголовок Accept-Language
Заголовок Accept-Language используется для указания языковых предпочтений пользователя. Он содержит список значений с коэффициентами качества (например, de, en;q=0.7). Значение по умолчанию часто задаётся в соответствии с языком графического интерфейса агента пользователя, но большинство браузеров позволяют выбрать другие языковые предпочтения.
Из-за увеличения энтропии на основе конфигурации изменённое значение может использоваться для снятия цифрового отпечатка пользователя. Не рекомендуется менять его, а веб-сайт не может полагаться на это значение как на точное отражение намерений пользователя. Дизайнерам сайтов лучше не определять язык с помощью этого заголовка, поскольку это может ухудшить взаимодействие с пользователем.
- Всегда следует предоставлять возможность переопределить выбранный сервером язык, например с помощью языкового меню на сайте. Большинство агентов пользователя задают для заголовка
Accept-Languageзначение по умолчанию, соответствующее языку интерфейса. Конечные пользователи часто не меняют его, потому что не знают как или не могут сделать это в своей вычислительной среде. - После того как пользователь переопределил выбранный сервером язык, сайт больше не должен определять язык автоматически и должен использовать явно выбранный язык. Иными словами, только начальные страницы сайта должны использовать этот заголовок для выбора подходящего языка.
Заголовок User-Agent
Примечание: Хотя этот заголовок можно обоснованно использовать для выбора содержимого, считается плохой практикой полагаться на него при определении поддерживаемых агентом пользователя возможностей.
Заголовок User-Agent идентифицирует браузер, отправивший запрос. Эта строка может содержать разделённый пробелами список токенов продукта и комментариев.
Токен продукта — это имя, за которым следуют / и номер версии, например Firefox/4.0.1. Агент пользователя может включить любое количество таких токенов. Комментарий — это необязательная строка в круглых скобках. Сведения в комментарии не стандартизированы, хотя некоторые браузеры добавляют в него несколько токенов, разделённых ;.
Заголовок ответа Vary
В отличие от рассмотренных выше заголовков Accept-*, которые отправляет клиент, HTTP-заголовок Vary отправляется веб-сервером в ответе. Он указывает список заголовков, которые сервер использует на этапе согласования содержимого по инициативе сервера. Заголовок Vary нужен, чтобы сообщить кешу критерии принятия решения, позволяя ему воспроизвести этот процесс. Благодаря этому кеш продолжает работать, обеспечивая отправку пользователю подходящего содержимого.
Специальное значение * означает, что при согласовании содержимого по инициативе сервера для выбора подходящего содержимого также используется информация, не передаваемая в заголовке.
Заголовок Vary был добавлен в версию HTTP 1.1 и позволяет кешам работать корректно. Для работы с согласованием содержимого по инициативе сервера кешу нужно знать, какие критерии сервер использовал для выбора передаваемого содержимого. Тогда кеш сможет повторить алгоритм и отправить приемлемое содержимое напрямую, не обращаясь снова к серверу. Очевидно, что подстановочный знак * исключает кеширование, поскольку кеш не может определить, какой элемент за ним скрывается. Дополнительные сведения см. в разделе Кеширование HTTP > Вариативность ответов.
Согласование по инициативе агента
У согласования по инициативе сервера есть несколько недостатков: оно плохо масштабируется. Для согласования используется по одному заголовку на каждую характеристику. Если нужно учитывать размер экрана, разрешение или другие параметры, придётся создать новый заголовок HTTP. Затем заголовки необходимо отправлять с каждым запросом. Если заголовков всего несколько, это не проблема, но с увеличением их числа размер сообщения может повлиять на производительность. Чем точнее передаваемые заголовки, тем больше информации они раскрывают, что повышает риск снятия цифрового отпечатка HTTP и создаёт соответствующие проблемы с конфиденциальностью.
HTTP допускает другой тип согласования: согласование по инициативе агента или реактивное согласование. В этом случае при неоднозначном запросе сервер отправляет страницу со ссылками на доступные альтернативные ресурсы. Пользователю показываются ресурсы, и он выбирает нужный.
К сожалению, стандарт HTTP не определяет формат страницы для выбора между доступными ресурсами, поэтому автоматизировать этот процесс невозможно. Помимо перехода к согласованию по инициативе сервера, этот метод почти всегда применяется со скриптами, особенно с перенаправлением на JavaScript: проверив критерии согласования, скрипт выполняет перенаправление. Ещё одна проблема заключается в необходимости дополнительного запроса для получения реального ресурса, из-за чего пользователю приходится дольше ждать его загрузки.
См. также
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Content_negotiation