Chrome is not sending if-none-match
One reason Chrome may not send If-None-Match
is when the response includes an "HTTP/1.0" instead of an "HTTP/1.1" status line. Some servers, such as Django's development server, send an older header (probably because they do not support keep-alive) and when they do so, ETags don't work in Chrome.
In the "Response Headers" section, click "view source" instead of the parsed version. The first line will probably read something like HTTP/1.1 200 OK
— if it says HTTP/1.0 200 OK
Chrome seems to ignore any ETag
header and won't use it the next load of this resource.
There may be other reasons too (e.g. make sure your ETag header value is sent inside quotes), but in my case I eliminated all other variables and this is the one that mattered.
UPDATE: looking at your screenshots, it seems this is exactly the case (HTTP/1.0 server from Python) for you too!
Assuming you are using Django, put the following hack in your local settings file, otherwise you'll have to add an actual HTTP/1.1 proxy in between you and the ./manage.py runserver
daemon. This workaround monkey patches the key WSGI class used internally by Django to make it send a more useful status line:
# HACK: without HTTP/1.1, Chrome ignores certain cache headers during development!# see https://stackoverflow.com/a/28033770/179583 for a bit more discussion.from wsgiref import simple_serversimple_server.ServerHandler.http_version = "1.1"
Also check that caching is not disabled in the browser, as is often done when developing a web site so you always see the latest content.
I had a similar problem in Chrome, I was using http://localhost:9000
for development (which didn't use If-None-Match
).
By switching to http://127.0.0.1:9000
Chrome1 automatically started sending the If-None-Match
header in requests again.
Additionally - ensure Devtools > Network > Disable Cache [ ]
is unchecked.
1 I can't find anywhere this is documented - I'm assuming Chrome was responsible for this logic.