Last Updated: February 25, 2016
·
1.08K
· thurloat

Mobile WebKit caches similar POSTs

This "bug" bit me today on both iOS6 and Android stock browsers. A login form which when your login is invalid, would forever (until clearing cookies & data in safari settings) reject login attempts.

HTTP spec specifies in the POST section (9.5) that:

Responses to [POST] method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.

And it appears as if they've implemented the spec backwards in that if you don't specifically mention "Cache-Control": "no-cache" from the server, POST requests that are similar will be cached without your consent.

There are two simple ways to get around this,

server

On all POST requests, include the "Cache-Control": "no-cache" Header on all responses.

Django users can simply $ pip install django-postleware and add the middleware in settings.py. (Project Home)

client

On all POST requests, use the trusted IE cache-busting hack of appending the timestamp of the request as a query parameter.

uri += "?cachebuster=" + (new Date()).getTime();

Of if you're using jQuery a slightly cleaner approach would be to use the $.ajaxSetup method like so:

// globally ensure that POSTs are sent with cache-control: no-cache 
// header so that responses aren't cached by the browser.
$.ajaxSetup({
    type: 'POST',
    headers: { "Cache-Control": "no-cache" }
});

Hope you (the reader) doesn't spend as much time fighting this damn bug as I did, as it can manifest in weird and unexpected ways.