84

For two subsequent requests, which of the following two headers is given more weight by browsers should one of them change: ETag or Last-Modified?

3 Answers 3

96

According to RFC 2616 – section 13.3.4, an HTTP 1.1 Client MUST use the ETag in any cache-conditional requests, and if both an ETag and Last Modified are present, it SHOULD use both. The ETag header is considered a strong validator (see section 13.3.3), unless explicitly declared weak by the server, whereas the Last Modified header is considered weak unless at least a minute difference exists between it and the Date header. Note, however that the Server is not required to send either (but it SHOULD, if it can).

Note that the Client does not check the headers to see if they have changed; it just blindly uses them in the next conditional request; it is up to the Server to evaluate whether to send the requested content or a 304 Not Modified response. If the Server only sends one, then the Client will use that one alone (although, only strong validators are useful for a Range request). Of course, it is also at the discretion of intermediate caches (unless they have been prevented from caching via Cache Control directives) and the Server as to how they will act upon the headers; the RFC states that they MUST NOT return a 304 Not Modified if the validators are inconsisent, but since the header values are generated by the server, it has quite a bit of leeway.

In practice, I have noticed that Chrome, FireFox, and IE 7+ all send both headers, if available. I also tested the behavior when sending modified headers, which I had already suspected from the information in the RFC. The four clients I tested only sent conditional requests if the page(s) were refreshed or if it was the first time the page had been requested by the current process.

2
  • 1
    Great answer, Thomas. Thanks for providing the official spec and discussing current browser implementations.
    – dthrasher
    Dec 21, 2009 at 18:47
  • 1
    Quoting from section 14.26, the server MUST NOT perform the requested method, unless required to do so because the resource's modification date fails to match that supplied in an If-Modified-Since header field in the request. Looks like If-Modified-Since takes precedence.
    – Vicary
    Jan 24, 2013 at 12:53
21

Isn't it more like an "OR" expression. In pseudo code:

if ETagFromServer != ETagOnClient || LastModifiedFromServer != LastModifiedOnClient
   GetFromServer
else
   GetFromCache
2
  • 4
    I think the last modified timestamp should be compared differently, as in: if ETagFromServer != ETagOnClient || LastModifiedFromServer > LastModifiedOnClient
    – RoyM
    Aug 31, 2014 at 15:32
  • It's an AND statement because the ETag may be weak in which case you could have a semantically equivalent entity and then you fall back on the last-modified header. Consider a situation where a picture could be re-encoded and we want to say the original and re-encoding are the same despite the fact they are not byte-identical. In this case we want to use the last-modified as a fallback and that is why they BOTH must be consistent
    – ParoX
    Mar 24, 2016 at 4:30
9

!= is the correct comparison operator. The client is required to keep the literal string received from the server, as conversions can create small differences. You can not assume that 'newer is better'.

Why? Consider the case where the server operator reverts a bad version of a resource. The reverted version is OLDER - but correct.

The client must use the version currently offered by the server; it can use a cached version only if it is the same. Thus the server must check equality, not 'newer'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.