When I send a 304 response. How will the browser interpret other headers which I send together with the 304?
E.g.
header("HTTP/1.1 304 Not Modified");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
Will this make sure the browser will not send another conditional GET request (nor any request) until $offset time has "run out"?
Also, what about other headers?
Should I send headers like this together with the 304:
header('Content-Type: text/html');
Do I have to send:
header("Last-Modified:" . $modified);
header('Etag: ' . $etag);
To make sure the browser sends a conditional GET request the next time the $offset has "run out" or does it simply save the old Last Modified and Etag values?
Are there other things I should be aware about when sending a 304 response header?
The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields.
A response header is an HTTP header that can be used in an HTTP response and that doesn't relate to the content of the message. Response headers, like Age , Location or Server are used to give a more detailed context of the response.
Request headers contain more information about the resource to be fetched, or about the client requesting the resource. Response headers hold additional information about the response, like its location or about the server providing it.
This blog post helped me a lot in order to tame the "conditional get" beast.
An interesting excerpt (which partially contradicts Ben's answer) states that:
If a normal response would have included an ETag header, that header must also be included in the 304 response.
Cache headers (Expires, Cache-Control, and/or Vary), if their values might differ from those sent in a previous response.
This is in complete accordance with the RFC 2616 sec 10.3.5.
Below a 200 request...
HTTP/1.1 200 OK
Server: nginx/0.8.52
Date: Thu, 18 Nov 2010 16:04:38 GMT
Content-Type: image/png
Last-Modified: Thu, 15 Oct 2009 02:04:11 GMT
Expires: Thu, 31 Dec 2010 02:04:11 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Content-Length: 6394
Via: 1.1 proxyIR.my.corporate.proxy.name:8080 (IronPort-WSA/6.3.3-015)
Connection: keep-alive
Proxy-Connection: keep-alive
X-Junk: xxxxxxxxxxxxxxxx
...And its optimal valid 304 counterpart.
HTTP/1.1 304 Not Modified
Server: nginx/0.8.52
Date: Thu, 18 Nov 2010 16:10:35 GMT
Expires: Thu, 31 Dec 2011 16:10:35 GMT
Cache-Control: max-age=315360000
Via: 1.1 proxyIR.my.corporate.proxy.name:8080 (IronPort-WSA/6.3.3-015)
Connection: keep-alive
Proxy-Connection: keep-alive
X-Junk: xxxxxxxxxxx
Notice that the Expires
header is at most Current Date + One Year
as per RFC-2616 14.21.
The Content-Type
header only applies to responses which contain a body. A 304 response does not contain a body, so that header does not apply. Similarly, you don't want to send Last-Modified
or ETag
because a 304 response means that the document hasn't changed (and so neither have the values of those two headers).
For an example, see this blog post by Anne van Kesteren examining WordPress' http_modified
function. Note that it returns either Last-Modified
and ETag
or a 304 response.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With