Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the function of the "Vary: Accept" HTTP header?

I use PHP to generate dynamic Web pages. As stated on the following tutorial (see link below), the MIME type of XHTML documents should be "application/xhtml+xml" when $_SERVER['HTTP_ACCEPT'] allows it. Since you can serve the same page with 2 different MIMEs ("application/xhtml+xml" and "text/html") you should set the "Vary" HTTP header to "Accept". This will help the cache on proxies.

Link: http://keystonewebsites.com/articles/mime_type.php

Now I'm not sure of the implication of: header('Vary: Accept'); I'm not really sure of what 'Vary: Accept' will precisely do...

The only explanation I found is:

After the Content-Type header, a Vary header is sent to (if I understand it correctly) tell intermediate caches, like proxy servers, that the content type of the document varies depending on the capabilities of the client which requests the document. http://www.456bereastreet.com/archive/200408/content_negotiation/

Anyone can give me a "real" explanation of this header (with that value). I think I understand things like: Vary: Accept-Encoding where the cache on proxies could be based on the encoding of the page served, but I don't understand: Vary: Accept

like image 401
AlexV Avatar asked Dec 29 '09 16:12

AlexV


People also ask

What is the use of vary header?

The Vary HTTP response header describes the parts of the request message aside from the method and URL that influenced the content of the response it occurs in. Most often, this is used to create a cache key when content negotiation is in use.

What is vary accept Encoding header?

It is allowing the cache to serve up different cached versions of the page depending on whether or not the browser requests GZIP encoding or not. The vary header instructs the cache to store a different version of the page if there is any variation in the indicated header.

What is the purpose of the HTTP Accept header?

The Accept request HTTP header indicates which content types, expressed as MIME types, the client is able to understand. The server uses content negotiation to select one of the proposals and informs the client of the choice with the Content-Type response header.

What is vary user agent?

The Role of Vary: User-AgentIt tells Dynamic caching which version of your page should be served depending on the browser type, which can prevent a cached desktop version being served to a mobile visitor.


1 Answers

  • The cache-control header is the primary mechanism for an HTTP server to tell a caching proxy the "freshness" of a response. (i.e., how/if long to store the response in the cache)

  • In some situations, cache-control directives are insufficient. A discussion from the HTTP working group is archived here, describing a page that changes only with language. This is not the correct use case for the vary header, but the context is valuable for our discussion. (Although I believe the Vary header would solve the problem in that case, there is a Better Way.) From that page:

Vary is strictly for those cases where it's hopeless or excessively complicated for a proxy to replicate what the server would do.

  • RFC2616 "Header-Field Definitions" describes the header usage from the server perspective, RFC2616 "Caching Negotiated Responses" from a caching proxy perspective. It's intended to specify a set of HTTP request headers that determine uniqueness of a request.

A contrived example:

Your HTTP server has a large landing page. You have two slightly different pages with the same URL, depending if the user has been there before. You distinguish between requests and a user's "visit count" based on Cookies. But -- since your server's landing page is so large, you want intermediary proxies to cache the response if possible.

The URL, Last-Modified and Cache-Control headers are insufficient to give this insight to a caching proxy, but if you add Vary: Cookie, the cache engine will add the Cookie header to its caching decisions.

Finally, for small traffic, dynamic web sites -- I have always found the simple Cache-Control: no-cache, no-store and Pragma: no-cache sufficient.

Edit -- to more precisely answer your question: the HTTP request header 'Accept' defines the Content-Types a client can process. If you have two copies of the same content at the same URL, differing only in Content-Type, then using Vary: Accept could be appropriate.

Update 11 Sep 12:

I'm including a couple links that have appeared in the comments since this comment was originally posted. They're both excellent resources for real-world examples (and problems) with Vary: Accept; Iif you're reading this answer you need to read those links as well.

The first, from the outstanding EricLaw, on Internet Explorer's behavior with the Vary header and some of the challenges it presents to developers: Vary Header Prevents Caching in IE. In short, IE (pre IE9) does not cache any content that uses the Vary header because the request cache does not include HTTP Request headers. EricLaw (Eric Lawrence in the real world) is a Program Manager on the IE team.

The second is from Eran Medan, and is an on-going discussion of Vary-related unexpected behavior in Chrome: Backing doesn't handle Vary header correctly. It's related to IE's behavior, except the Chrome devs took a different approach -- though it doesn't appear to have been a deliberate choice.

like image 113
J.J. Avatar answered Oct 14 '22 21:10

J.J.