10

How do I prevent the client browser from rendering its cached version for a page, so that it must always perform a GET when the visitor visits the page?

I am using Django's @never_cache decorator in the view, which adds "Cache-Control:max-age=0" to the HTTP GET header. However when I visit the page (in Google Chrome and Firefox, the only browsers I have tested so far), the cached version is inevitably rendered. (Confirmed by visiting the Network tab for the request, which reports "200 OK (from cache)".)

If I now click the Refresh button, it will render the fresh content from the server (Network tab for the request says "200 OK" and the headers as shown below.)

In lieu of setting "Cache-Control:max-age=0" I also tried setting the "Expires" HTTP header parameter to be a date in the past. This did not work either.

Request Method:GET
Status Code:200 OK

Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
If-Modified-Since:Fri, 17 Feb 2012 15:25:21 GMT
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11

Response Headers
Cache-Control:max-age=0
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Fri, 17 Feb 2012 15:55:11 GMT
ETag:"[removed]"
Expires:Fri, 17 Feb 2012 15:55:11 GMT
Last-Modified:Fri, 17 Feb 2012 15:55:11 GMT
Server:nginx
Transfer-Encodindg:chunked
Vary:Cookie,Accept-Encoding
X-Handled-By:127.0.0.1:8000
ram1
  • 6,290
  • 8
  • 41
  • 46
  • Does using "no-cache" instead fix the issue? See here: http://stackoverflow.com/questions/1046966/whats-the-difference-between-cache-control-max-age-0-and-no-cache not sure how to set that from Django though. – Graham Conzett Feb 17 '12 at 16:47
  • I haven't tried that. Doing so now... – ram1 Feb 17 '12 at 16:51
  • That did not work, Graham. I set the Cache-Control header to "no-cache" and still Chrome delivers the cached version of the page, preventing the GET request. Again, I can click Chrome's Refresh button at this point to get the fresh content -- but naturally I want to prevent users from having to do that. – ram1 Feb 17 '12 at 17:09
  • 1
    I should note that StackOverflow appears to have a similar problem. After I clicked the red "1" in the header to read Graham's comment, I clicked the link he shared which redirected me to another page -- and even though I had already read his message I saw the red "1" in the header. I assumed it was a new message, so clicked the "1" again but no one else had commented. The "1" disappeared (again) and after I had finished reading the page I clicked Chrome's back button -- and there was the "1" in the header again. I clicked it again, but there were no new messages for me to read. – ram1 Feb 17 '12 at 17:20
  • This is only tangentially related to your problem, but you can't count on the browser to refresh **any** content when you click the Back button. WebKit caches entire pages, DOM and all, so that clicking back and forth through your history will immediately load previously visited pages. See [this article on the WebKit page cache](http://www.webkit.org/blog/427/webkit-page-cache-i-the-basics/). – Brandan Feb 21 '12 at 01:45

2 Answers2

12

In your response set these:

response['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate' 
response['Expires'] = 'Fri, 01 Jan 2010 00:00:00 GMT'

It's how Google Docs enforces pages refresh at all times.

Then you can play with it to find the ideal behaviour for your purposes.

Tomasz Zieliński
  • 16,136
  • 7
  • 59
  • 83
  • 1
    I can see that this is forcing chrome to request the page from my server, but it doesn't look like it is rendering the HTML that is returned. Specifically, I have a value that gets added to an attribute on save. When I hit the back button, I see that chrome requested the page again, but when I inspect the element, the value isn't added. When I view the source however, I see that the value has been correctly added to the element. On Firefox everything is working properly. – wildehahn May 07 '13 at 01:22
  • @wildehahn Firefox works a bit differently - it supports back-forward cache. Not sure what the problem is here but maybe bf cache causes the difference you observe. – Tomasz Zieliński May 07 '13 at 01:47
  • Thank you so much! – ihatecache Nov 03 '16 at 20:23
1

Have you tried this in your htaccess file:

<FilesMatch "\.(css|gif|html|jpg|js|php|png)$">
Header set Cache-Control: "max-age=0, no-store"
</FilesMatch>

You can adjust the files match line for a specific page/path and also for specific assets

Alexander Holsgrove
  • 1,795
  • 3
  • 25
  • 54