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