Chrome and Safari caching 302 redirect

14,447

cache-control: no-store

I had the same maddening problem that you described (slightly different in that it was a missing cookie redirect back to the login page) that worked everywhere but Safari.

In desperation, I came across this open WebKit bug and saw the fateful comment (and finally a glimmer of hope):

CachedRawResource now keeps the redirect chain, and has some trivial logic for checking correctness, but it's nowhere near complete (only checks cacheControlContainsNoStore()). And of course other resource types don't have anything.

Added no-store to my cache-control header and no more problem.

Share:
14,447
rpmartz
Author by

rpmartz

Updated on July 26, 2022

Comments

  • rpmartz
    rpmartz almost 2 years

    Various flavors of this have been asked already, but I've yet to see a real answer for this.

    We have a separate image service that our web app uses to get some of its images. The image service is well tested and is functioning properly. To make it concrete, our app is served from domain.com. The src element of img elements is images.domain.com/{imageId}. The image service retrieves the URL for the image and sends back a HTTP 302 redirect for the image.

    The application allows users to change images. So say a user 5 has image A as a profile image, and decides to change it by uploading image B. When the user uploads the image, the application cache is properly invalidated and the database is updated. The application does a standard redirect after POST and one of the elements in the page that the user is redirected to after changing her image is something like:

     <img src="example.domain.com/5">
    

    The problem is that Chrome never makes the call to example.domain.com/5 to retrieve the image upon the initial redirect or a regular reload of the page, it simply serves image A from the browser cache. A standalone call to example.domain.com/5 correctly returns image B, and a hard refresh or clearing Chrome's cache forces Chrome to request the image's src, which correctly returns image B. Note that I'm not talking about serving either image from the cache after getting a 304 Not Modified response, I'm talking about Chrome deciding not to visit the img src at all and just returning image A. Also, appending some unique query string to the img's src attribute fixes the problem, but that's a hack that we'd rather not have to do.

    It's worth noting that Firefox was doing the same thing initially. There were no Cache Control headers in the response initially. We added a Cache Control: no-cache header (and tried no-store as well) to the response header and this fixed the behavior in Firefox, but Chrome and Safari still serve the outdated, cached image without making a call to the image's src.

    It looks like this was a longstanding bug in Chromium (https://code.google.com/p/chromium/issues/detail?id=103458) that's allegedly fixed as of about 6 weeks ago, but we're using the most updated version of Chrome.

    We've looked at the answers here and here but they don't actually answer the question.

    Per section 14.9.1 of RFC 2616:

    If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.

    Unless we're missing something or doing something wrong, it would seem that Chrome (and Safari) are not complying the RFC behavior for no-cache headers for 302 redirects? Anyone experience this before or have any insight?