Какова функция HTTP-заголовка "Vary: Accept"?

Я использую PHP для создания динамических веб-страниц. Как указано в следующем учебном пособии (см. Ссылку ниже), MIME-тип документов XHTML должен быть "application/xhtml + xml", когда это разрешает $_SERVER ['HTTP_ACCEPT']. Поскольку вы можете обслуживать одну и ту же страницу с двумя разными MIME ( "application/xhtml + xml" и "text/html" ), вы должны установить HTTP-заголовок "Vary" в "Accept". Это поможет кешу прокси.

Ссылка: http://keystonewebsites.com/articles/mime_type.php

Теперь я не уверен в следующем: header ('Vary: Accept'); Я не совсем уверен, что "Вари: Принять" будет точно...

Единственное объяснение, которое я нашел, это:

После заголовка Content-Type, Vary заголовок отправляется (если я его понимаю правильно) рассказать промежуточные тайники, как прокси-серверы, что контент тип документа изменяется в зависимости от о возможностях клиента который запрашивает документ. http://www.456bereastreet.com/archive/200408/content_negotiation/

Любой может дать мне "реальное" объяснение этого заголовка (с этим значением). Я думаю, что понимаю такие вещи, как: Vary: Accept-Encoding где кеш на прокси-серверах может быть основан на кодировке обслуживаемой страницы, но я не понимаю: Vary: Принять

Ответ 1

  • Заголовок cache-control является основным механизмом для HTTP-сервера, который сообщает кэширующему прокси "свежесть" ответа, (т.е. как/если долго хранить ответ в кеше)

  • В некоторых ситуациях директивы cache-control недостаточны. Обсуждение рабочей группы HTTP архивируется здесь, описывая страницу, которая изменяется только на языке. Это неправильный вариант использования для заголовка переменной, но этот контекст является ценным для нашего обсуждения. (Хотя я считаю, что заголовок Vary решит проблему в этом случае, есть лучший способ.) С этой страницы:

Vary строго для тех случаев, когда он безнадежно или чрезмерно усложняется для прокси-сервера для репликации того, что будет делать сервер.

Надуманный пример:

Ваш HTTP-сервер имеет большую целевую страницу. У вас есть две несколько разные страницы с одинаковым URL-адресом, в зависимости от того, был ли пользователь раньше. Вы различаете запросы и пользователь "посещают счет" на основе Cookies. Но, поскольку ваша целевая страница сервера настолько велика, вы хотите, чтобы посреднические прокси кэшировали ответ, если это возможно.

Заголовки URL, Last-Modified и Cache-Control недостаточно, чтобы дать это представление прокси-серверу кэширования, но если вы добавите Vary: Cookie, механизм кэширования добавит заголовок Cookie к его решениям кэширования.

Наконец, для небольшого трафика динамические веб-сайты - я всегда считал простые Cache-Control: no-cache, no-store и Pragma: no-cache достаточными.

Изменить - чтобы более точно ответить на ваш вопрос: заголовок HTTP-запроса "Принять" определяет типы контента, которые клиент может обработать. Если у вас есть две копии одного и того же контента по одному и тому же URL-адресу, отличающиеся только содержимым-типом, то использование Vary: Accept может быть подходящим.

Обновление 11 сентября 12:

Я включаю пару ссылок, которые появились в комментариях, поскольку этот комментарий был первоначально опубликован. Они оба отличные ресурсы для реальных примеров (и проблем) с помощью Vary: Accept; Если вы читаете этот ответ, вам также нужно прочитать эти ссылки.

Первый, от выдающегося EricLaw, от поведения Internet Explorer с заголовком Vary и некоторыми проблемами, которые он представляет разработчикам: Vary Header предотвращает кеширование в IE. Короче говоря, IE (pre IE9) не кэширует какой-либо контент, который использует заголовок Vary, потому что кэш запросов не включает заголовки HTTP-запроса. EricLaw (Эрик Лоуренс в реальном мире) является менеджером программ в команде IE.

Второе - от Eran Medan, и это постоянное обсуждение неожиданного поведения, связанного с Vary, в Chrome: Резервное копирование не обрабатывает заголовок Vary правильно. Это связано с поведением IE, за исключением того, что разработчики Chrome использовали другой подход, хотя он, похоже, не был преднамеренным выбором.

Ответ 2

Vary: Accept просто говорит, что ответ был сгенерирован на основе заголовка Accept в запросе. Запрос с другим заголовком Accept может получить другой ответ.

(Вы можете видеть, что связанный PHP-код выглядит с $HTTP_ACCEPT. Это значение заголовка запроса Accept.)

В кэши HTTP это означает, что ответ должен быть кэширован с особой осторожностью. Он будет действительным только для последующих запросов с точно таким же заголовком Accept.

Теперь это имеет значение только в том случае, если страница является кешируемой в первую очередь. По умолчанию страницы PHP не являются. Страница PHP может пометить вывод как кешируемый путем отправки определенных заголовков (например, Expires). Но нужно ли и как это сделать, это другой вопрос.

Ответ 3

На самом деле на данный момент появилось значительное количество новых функций (и уже в Chrome), которые делают заголовок Vary чрезвычайно полезным. Например, рассмотрите подсказку клиента. Например, при использовании в сочетании с изображениями подсказка клиента позволяет серверу оптимизировать ресурсы, такие как изображения, в зависимости от:

  • Ширина изображения
  • Ширина окна просмотра
  • Тип кодирования, поддерживаемый браузером (думаю, WebP)
  • Вниз (по существу, скорость сети)

Таким образом, сервер, который поддерживает эти функции, установит заголовок Vary, чтобы указать это.

Chrome рекламирует поддержку WebP, устанавливая "image/webp" как часть заголовка Vary для каждого запроса. Таким образом, сервер может переписать образ как WebP, если браузер поддерживает его, поэтому прокси-сервер должен будет проверить заголовок, чтобы не кэшировать образ WebP, а затем обслуживать его в браузере, который не поддерживает WebP. Очевидно, если ваш сервер этого не сделает, это не имеет значения. Так как ответ сервера зависит от заголовка запроса Accept, ответ должен включать это, чтобы не путать прокси:

Vary: Accept

Другим примером может быть ширина изображения. В мобильном браузере заголовок Width может быть довольно мал для отзывчивого изображения, по сравнению с тем, что он будет, если смотреть с браузера рабочего стола. Поэтому в этом случае Width будет добавлен в заголовок Vary, чтобы прокси-сервер не кэшировал небольшую мобильную версию и не обслуживал ее на настольных браузерах, или наоборот. В этом случае заголовок может включать:

Vary: Accept, Width

Или в том случае, если сервер поддерживает все спецификации подсказки клиента, заголовок будет выглядеть примерно так:

Vary: Accept, DPR, Width, Save-Data, Downlink