15

I am using ASP.NET WebApi and have the following code to stop caching in everything:

public override System.Threading.Tasks.Task<HttpResponseMessage> ExecuteAsync(System.Web.Http.Controllers.HttpControllerContext controllerContext, System.Threading.CancellationToken cancellationToken)
{
    System.Threading.Tasks.Task<HttpResponseMessage> task = base.ExecuteAsync(controllerContext, cancellationToken);
    task.GetAwaiter().OnCompleted(() =>
                                      {
                                          task.Result.Headers.CacheControl = new CacheControlHeaderValue()
                                          {
                                              NoCache = true,
                                              NoStore = true,
                                              MaxAge = new TimeSpan(0),
                                              MustRevalidate = true
                                          };
                                          task.Result.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));
                                          task.Result.Content.Headers.Expires = DateTimeOffset.MinValue;
                                      });
    return task;
}

The result headers look like this (chrome):

Cache-Control:no-store, must-revalidate, no-cache, max-age=0
Content-Length:1891
Content-Type:application/json; charset=utf-8
Date:Fri, 19 Jul 2013 20:40:23 GMT
Expires:Mon, 01 Jan 0001 00:00:00 GMT
Pragma:no-cache
Server:Microsoft-IIS/8.0

I added the "no-store" after reading about the bug (How to stop chrome from caching).

However, no matter what I do, when I do something that navigates me away from this page, and then use the "back" button, chrome always loads from cache:

Request Method:GET
Status Code:200 OK (from cache)

Does anyone have any idea why this is happening? I have confirmed that the server is never hit for this request.

Community
  • 1
  • 1
automaton
  • 1,972
  • 5
  • 25
  • 40

1 Answers1

8

The answer is that Chrome does not like "Expires:Mon, 01 Jan 0001 00:00:00 GMT" (a fake date, basically).

I changed my date to be what they use in their Google API, and it worked:

Cache-Control:no-store, must-revalidate, no-cache, max-age=0
Content-Length:1897
Content-Type:application/json; charset=utf-8
Date:Fri, 19 Jul 2013 20:51:49 GMT
Expires:Mon, 01 Jan 1990 00:00:00 GMT
Pragma:no-cache
Server:Microsoft-IIS/8.0

So, for anyone else who comes across this problem, make sure you set your Expires date to this arbitrary date!

automaton
  • 1,972
  • 5
  • 25
  • 40
  • 1
    If you have set no-store, then don't set no-cache, must-revalidate, max-age and expires as they contradict no-store. No-store means that the representation cannot be stored and the rest of the instructions explain the rules for managing stored representations. – Darrel Miller Jul 22 '13 at 02:46
  • well i just added no-store because of the chrome bug that ignores no-cache and expires (see http://stackoverflow.com/questions/4146813/how-to-stop-chrome-from-caching)... so, i don't know what you want me to do about that. – automaton Jul 22 '13 at 17:08
  • Unfortunately no-cache doesn't mean don't cache. It also doesn't mean that Chrome can't use the cached copy. It just means that it must check with the server before using the cached copy. If the server doesn't return the correct information chrome will happily return the cached result. – Darrel Miller Jul 22 '13 at 18:17
  • 1
    both of these: http://www.i18nguy.com/markup/metatags.html and http://stackoverflow.com/questions/866822/why-both-no-cache-and-no-store-should-be-used-in-http-response indicate that "no-cache" does indeed mean don't cache, but no-store means it can cache but don't allow archiving – automaton Jul 22 '13 at 19:15
  • 3
    I would suggest reading the official documentation on the subject http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-23#section-7.2.2 – Darrel Miller Jul 23 '13 at 13:37
  • 2
    IETF? really? that's like pointing me to the w3c for what is 'proper'. let's keep in mind that this is business, and in business it doesn't matter what is right, what matters is what works. and it's pretty clear that current browser implementation do NOT follow what the IETF says is 'correct' – automaton Jul 23 '13 at 14:49
  • 3
    That bug report you linked to was closed along with a second one he created because the OP did not understand how caching works. The Chrome team and the people who work on caching proxies like squid are heavily involved in the work of the IETF. The SO posts you linked to are just further examples of people not reading the specs carefully. – Darrel Miller Jul 23 '13 at 15:16