96

What could be the difference between if-modified-since and if-none-match? I have a feeling that if-none-match is used for files whereas if-modified-since is used for pages?

Tower
  • 98,741
  • 129
  • 357
  • 507

7 Answers7

118

Regarding the differences between Last-Modified/If-Modified-Since and ETag/If-None-Match:

Both can be used interchangeably. However depending on the type of resource, and how it is generated on the server, one or the other question ("has this been modified since ...?" / "does this still match this ETag?") may be easier to answer.

Examples:

  • If you're serving files, using the file's mtime as the Last-Modified date is the simplest solution.
  • If you're serving a dynamic web page built from a number of SQL queries, checking whether the data returned by any of those queries has changed may be impractical (unless all of them have some sort of "last modified" column). In this case, using e.g. an md5 hash of the page content as the ETag will be a lot easier.
    OTOH, this means that you still have to generate the whole page on the server, even for a conditional GET. Figuring out what exactly has to go into the ETag (primary keys, revision numbers, ... etc.) can save you a lot of time here.

See these links for more details on the topic:

trendels
  • 4,747
  • 3
  • 26
  • 16
  • I've sent the browser an ETag, but it never requests the same page with If-None-Match. What may be the problem? – Pacerier Jul 12 '12 at 02:27
  • 2
    @pacerier: Browsers are not required to use Etag. So it could be an old browser and simply ignoring it. The other possibility is that the entity is being accessed with url parameters that change from call to call. If the entity name changes then etag wont be used for different requests. – Rafael Baptista May 24 '13 at 21:20
  • @RafaelBaptista To elaborate more on your second half of the comment, say I have this situation: I have a file server and the server supports versioning using ETags and for backwards compatibility reasons, we used to have clients use a query parameter my_current_version=(version). If I send a HTTP request with varying values for my_current_version, but also with ETags, then what criterion, as a best practice, will be prioritized when determining whether to serve a new version or send back a 304? Thanks! – laughing_man Apr 14 '15 at 20:56
  • 1
    How the server uses Etag is up to the server. You can probably configure most file servers to ignore parameters with etag if you want via rewrite rules. You have less control over the client - the browser. Most will not send an etag header that they got for one set of parameters in a request for another. A client request for image?v=1 will not sent the same etag for image?v=2. If I was writing my own servers I would implement etag as a hash of the image contents. Any url that asks for a resource, and comes with an etag that matches the hash of the image I would send, I return 304. – Rafael Baptista Apr 15 '15 at 21:42
24

If-Modified-Since is compared to the Last-Modified whereas If-None-Match is compared to ETag. Both Modified-Since and ETag can be used to identify a specific variant of a resource.

But the comparison of If-Modified-Since to Last-Modified gives you the information whether the cached variant is older or newer whereas the comparison of If-None-Match to ETag just gives you the information whether both are identical or not. Furthermore do most of the ETag generators include the information of the system specific inode so moving a file to a different drive may change the ETag as well.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • Interesting, but why would I use "identical" checks over "last modified" checks? What are the benefits? If a have a file to serve, which one is a better option? – Tower Jun 16 '09 at 15:48
  • 8
    With computers, time is fragile. Leap seconds, switching between day light savings time, and inaccurate clocks, can all cause a "last modified" check to return the wrong result. Comparing the content itself (or MD5 hash of the content) avoids those issues. – devdanke Dec 12 '12 at 07:38
  • Despite that I fully understand @devdanke, I would say that checking timestamp is much faster than checking md5sum. The purpose of these headers is to make it fast, sometimes it's preferred not to transfer fresh version of an entity to the client than load the server with I/O. Anyway, the user can always press ctrl+shift+R (or ctrl+F5 or whatever) – Grief Mar 17 '16 at 00:50
  • In the case of files and directories, time isn't really so fragile. The last-modified time comes from the mtime field of the stat system call, which comes directly from the filesystem, where it is stored as the number of seconds since the epoch. The mtime value is updated when a file is modified. The mtime is relative to the epoch, it does not change due to changes in the local clock. daylight savings, etc. Note that the local time, or time changes, of the browser is not important here - the browser just stores the value sent the server, then re-sends it in future requests. – bain May 04 '21 at 10:33
13

Timestamp value used in Last-Modified/If-Modified-Since has limited precision - one second and that is simply not enough for fast changing content like, for instance, Web-chat application where more than one message could be posted at any given second. ETag/If-None-Match can help to solve that problem.

Alex K
  • 633
  • 6
  • 11
12

As it is stated in google's best practices :

It is important to specify one of Expires or Cache-Control max-age, and one of Last-Modified or ETag, for all cacheable resources. It is redundant to specify both Expires and Cache-Control: max-age, or to specify both Last-Modified and ETag.

https://developers.google.com/speed/docs/best-practices/caching

Botz3000
  • 39,020
  • 8
  • 103
  • 127
Dionysios Arvanitis
  • 1,133
  • 9
  • 11
  • that URL no longer has text similar to that. No restriction against using `Last-Modified` with `ETag` (or, on the useragent side, `If-Modified-Since` with`If-None-Match`) is mentioned. Similarly the W3 spec doesn't restrict you. It says not to use `If-Modified-Since` with `If-Match`, but I assume that's because the set of documents that have updated dates but the same content as defined by the ETag should be quite small. – mpag Feb 12 '16 at 00:50
6

If-Modified-Since uses a date, while If-None-Match uses an ETag. They can both be used for "pages" (i.e. HTML) and other files.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
3

Unless stated as weak by the server, an ETag is considered a strong validator, and can thus be used to satify a conditional ranged request. However, most automatically generated ETags exhibit difficulties in server farm situations, since they often use inode information and / or a unique persistent counter. In practice, I have found the Last Modified header to be sufficient for fairly static content, e.g. serving up protected static content, since the write time of the file makes a reasonably good validator.

The ETag is by far the most flexible. Conforming clients are required to send the ETag in a conditional request, whereas they SHOULD send both if available.

Thomas S. Trias
  • 1,294
  • 9
  • 10
1

The If-Modified-Since header is used to specify the time at which the browser last received the requested resource. The If-None-Match header is used to specify the entity tag that the server issued with the requested resource when it was last received.

In the two ways described, these headers are used to support caching of content within the browser, and they enable the server to instruct the browser to use a cached copy of a resource, rather than responding with the full contents of the resource if this is not necessary.

Serhan M.
  • 11
  • 1
  • 2