5

When I unset the Last-Modified header in Apache (ETags are also disabled), Firefox (4.01) will not cache any file regardless of whether I set a future Expires header or enable the Cache-Control header.

So is the Last-Modified (and/or an ETag) header required for browser caching?

From here:

If no validator (an ETag or Last-Modified header) is present on a response, and it doesn’t have any explicit freshness information, it will be considered uncacheable.

... well, if by "Freshness Information" they mean "Cache-Control" or "Expires" header, Firefox should be caching without the Last-Modified header.

EDIT FOR FURTHER FIREFOX INFO

Note that no attempt to generate a 304 on any PHP file served by Apache 2.2 in Firefox 4.01 is successful (reload, fresh visit, etc.) without a Last-Modified header, regardless of any combination being set of a valid caching Cache-Control header, the Expires header or both headers.

foo.php: content of this file simply echoes 'Hello World'.

HTTP/1.1 200 OK
Date: Mon, 06 Jun 2011 14:04:58 GMT
Server: Apache
Cache-Control: public, max-age=3600
Expires: Fri, 01 Jul 2011 21:23:55 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 1594
Keep-Alive: timeout=10, max=500
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

EDIT FOR EVEN MORE STRANGE FIREFOX 4.01 FINDINGS

Even stranger, based on what I've seen with Firefox 4.01, no form of server-side cache control headers (Expires and/or Cache-Control) influence Firefox's caching behavior. Firefox only cares about Freshness information (Etag or Last-Modified).

In summary, if the file has been modified, Firefox reloads it, regardless of any Expires or Cache-Control headers. If the file doesn't contain any Freshness information, Firefox reloads it no matter what.

If anyone finds out differently in their observations, please update me.

ANOTHER EDIT

From this link:

13.2.1 Server-Specified Expiration

An expiration time cannot be used to force a user agent to refresh its display or reload a resource; its semantics apply only to caching mechanisms, and such mechanisms need only check a resource's expiration status when a new request for that resource is initiated. See section 13.13 for an explanation of the difference between caches and history mechanisms.

Jeff
  • 1,416
  • 3
  • 28
  • 50

2 Answers2

2

Be wary of reading random articles on the net (although Mark Nottingham's stuff is usually sensible). The definitive source should always by the RFCs. And according to RFC 2616 a browser should cache a document with an Expires: header where the timestamp is in the future, or where other valid caching instructions are provided provided that the document is not returned in response to a POST request.

It's perfectly valid to set a max-age without a last-modified - and the spec explicitly addresses that.

Certainly what you describe seems very unusual and implies that FF4.01 will never cache content - I would be amazed that it passed the QC checks with such a glaring omission. Can you provide details of the requests and responses proving this (e.g. with liveheaders)?

symcbean
  • 21,009
  • 1
  • 31
  • 52
0

It varies across browsers as to exactly what is needed, but generally I work using the theory that if content is going to be cached properly it needs at least a Last-Modified & Etag header, Expires is a plus but if it has an etag the browser will generally prioritize that over anything else.

  • I appreciate the feedback. From what I gather, ETags aren't always compatible under certain circumstances (CDN's, etc.). Do you happen to know if the Last-Modified header is actually required for proper caching? My experience says it is, but maybe I'm doing something wrong. – Jeff Jun 06 '11 at 00:29
  • I don't think it's required, but it's recommended. If you want total un-cachability set Expires to in the past and Last-modified to in the future (It doesn't sound logical that something can be modified in the future, but browsers will just say 'Is the Last-modified date higher than the last time I accessed this content'.) If you want total cachability set last modified to a long time in the past, and expires to a long time in the future. Adding ETags is a plus, as are correct Pragma headers. Any browsers/clients that don't support any of the headers will just ignore them –  Jun 06 '11 at 02:10