Chrome doesn't send "If-Modified-Since"
Asked Answered
B

6

11

I want browsers to always add (except first time) "If-Modified-Since" request header to avoid unnecessary traffic.

Response headers are:

Accept-Ranges:bytes
Cache-Control:max-age=0, must-revalidate
Connection:Keep-Alive
Content-Length:2683
Content-Type:text/html; charset=UTF-8
Date:Thu, 05 Apr 2012 13:06:19 GMT
Keep-Alive:timeout=15, max=497
Last-Modified:Thu, 05 Apr 2012 13:05:11 GMT
Server:Apache/2.2.21 (Red Hat)

FF 11 and IE 9 both send "If-Modified-Since" and get 304 in response but Chrome 18 doesn't and get 200.

Why? How to force Chrome to sent "If-Modified-Since" header? I do not know if it important or not but all requests going through HTTPS.

Bloodstream answered 6/4, 2012 at 7:48 Comment(3)
At the end of the day, it's up to the browsers, and any intermediate caches, whether they will actually cache content (you can control whether they should). You won't be able to 100% prevent user agents from re-requesting content.Norinenorita
I've noticed that Chrome doesn't send the If-Modified-Since header unless the response is gzip'd. I'm not sure if that's a real pattern or just my experience trying to deal with updating JS files.Mata
Any particular reason for sending Keep-Alive?Lucialucian
M
30

I've been chasing this issue for some time, thought I'd share what I found.

"The rule is actually quite simple: any error with the certificate means the page will not be cached."

https://code.google.com/p/chromium/issues/detail?id=110649

If you are using a self-signed certificate, even if you tell Chrome to add an exception for it so that the page loads, no resources from that page will be cached, and subsequent requests will not have an If-Modified-Since header.

Measurable answered 18/7, 2013 at 7:13 Comment(0)
G
8

I just now found this question, and after puzzling over Chrome's If_Modified_Since behavior, I've found the answer.

Chrome's decision to cache files is based on the Expires header that it receives. The Expires header has two main requirements:

  1. It must be in Greenwich Mean Time (GMT), and
  2. It must be formatted according to RFC 1123 (which is basically RFC 822 with a four-digit year).

The format is as follows:

Expires: Sat, 07 Sep 2013 05:21:03 GMT

For example, in PHP, the following outputs a properly formatted header.

$duration = time() + 3600 // Expires in one hour.
header("Expires: " . gmdate("D, d M Y H:i:s", $duration) . " GMT");

("GMT" is appended to the string instead of the "e" timezone flag because, when used with gmdate(), the flag will output "UTC," which RFC 1123 considers invalid. Also note that the PHP constants DateTime::RFC1123 and DATE_RFC1123 will not provide the proper formatting, since they output the difference to GMT in hours [i.e. +02:00] rather than "GMT".)

See the W3C's date/time format specifications for more info.

In short, Chrome will only recognize the header if it follows this exact format. This, combined with the Cache-Control header...

header("Cache-Control: private, must-revalidate, max-age=" . $duration);

...allowed me to implement proper cache control. Once Chrome recognized those headers, it began caching the pages I sent it (even with query strings!), and it also began sending the If_Modified_Since header. I compared it to a stored "last-modified" date, sent back HTTP/1.1 304 Not Modified, and everything worked perfectly.

Hope this helps anyone else who stumbles along!

Guillot answered 26/9, 2013 at 17:54 Comment(1)
Thanks, the GMT timezone was my issue I didn't notice :)Ambary
E
5

I've noticed almost the same behaviour and my findings are:

  • First of all the 200 status indicator in chrome is not the whole truth, you need to look at the "Size Content" column as well. If this says "(from cache)" the resource was take directly from cache without even asking if it was modified.

  • This caching behaviour of resources that lack any indication of expires or max-age seems to apply when requesting static files that have a last-modified header. I've noted that chrome (ver. 22):

    1. Asks for the file the first time (obviously since it is not in cache).
    2. Asks if it is modified the second time (since it is in cache but has no indication of freshness).
    3. Uses it directly the third time and then on (even if it is a new browser session).
  • I'm a bit puzzled by this behaviour but it is fairly reasonable, if it is static, was modified a long time ago, and hasn't changed since last check you could assume that it is going to be valid for a while longer (don't know how they calculate it though).

Epimenides answered 5/11, 2012 at 13:40 Comment(2)
Hi @Albert Bertilsson 1. asks for the file the first time ** 2. ** 3.** , is this your conclusion? I don't think it's right, which policy the chrome cache used should be LM-Factor, not what you said. If you ref this from google official doc, please past the link, thx a lot.Tapia
Regarding your last point, how would the browser know whether a file is static?Rainger
T
3

I had the same problem, in Chrome all requests were always status code 200, in other browsers 304.

It turned out I had the disable cache (while DevTools is open) checked in on Devtools - Settings - General page..:)

Tropous answered 3/3, 2014 at 18:25 Comment(0)
J
2
  1. Don't disable cache in Chrome Dev Tools (on "Network" tab).
  2. Cache-Control should be Cache-Control: public. Use true as second parameter to header PHP function: header("Cache-Control: public", true);
Jacynth answered 13/11, 2017 at 17:12 Comment(0)
C
0

I have also found that Chrome (recent v95+) also returns a cached 200 response if I have DevTools open. It never even sends the request on to the server! If I close DevTools, the behaviour is as it should, and the server receives the expected request.

Cochleate answered 22/12, 2021 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.