Rectangle 27 0

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


(You can see that the linked PHP code looks at $HTTP_ACCEPT. That's the value of the Accept request header.)

@Pacerier "might get" is correct. Vary: Accept does not mean that every single possible distinct Accept header value produces a different and unique response. It only means that a different Accept header might produce a different response.

Now this only matters if the page is cacheable in the first place. By default, PHP pages aren't. A PHP page can mark the output as cacheable by sending certain headers (Expires, for example). But whether and how to do that is a different question.

To HTTP caches, this means that the response must be cached with extra care. It is only going to be a valid match for later requests with exactly the same Accept header.

Vary: Accept simply says that the response was generated based on the Accept header in the request. A request with a different Accept header might get a different response.

is it "might get" or is it "should get" ?

Note
Rectangle 27 0

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


Vary
  • 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.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

Beware of this in conjunction with back browser button in Chrome, there is sort of a flame war on this bug (which is now wontfix for some reason) code.google.com/p/chromium/issues/detail?id=94369

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.

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

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 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.

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.

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.

Note
Rectangle 27 0

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


This google webmaster video has a very good explanation about HTTP Vary header.

Note
Rectangle 27 0

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


Vary: Accept
Vary: Accept, DPR, Width, Save-Data, Downlink
Vary: Accept, Width
  • Type of encoding supported by browser (think WebP)

Another example might be image width. On a mobile browser the Width header might be quite small for a responsive image, in comparison with what it would be if viewed from a desktop browser. So in that case Width would be added to the the Vary header is essential for proxy to not cache the small mobile version and serve it to desktop browsers, or vice versa. In that case, the header might include:

Chrome advertises WebP support by setting "image/webp" as part of the Vary header for each request. So a server might rewrite an image as WebP if the browser supports it, so the proxy would need to check the header so as to not cache a WebP image and then serve it to a browser that doesn't support WebP. Obviously, if your server doesn't do that, it wouldn't matter. So since the server's response varies on the Accept request header, the response must include that so as not to confuse proxies:

Or in the case that a server supported all of the client hinting specs, the header would be something like:

So a server which supports those features would set the Vary header to indicate that.

There are actually a significant number of new features coming soon (and already in Chrome) that make the Vary header extremely useful. For example, consider Client Hinting. When used in connection with images, for example, client hinting allows a server to optimize resources such as images depending on:

Note