iOS 6 cached POST-Requests … und wie man das verhindert

Letzte Woche haben wir uns ziemlich gewundert als uns aufgefallen ist, dass unsere iPhones mit iOS 6 nicht mehr mit unserer Web App funktioniert haben. Da sind wir wohl über ein “Feature” von iOS 6 gestolpert, das ziemlich viel Aufsehen in der Entwicklergemeinde verursacht hat, als es veröffentlicht wurde.

Um dem Benutzer noch das letzte bisschen Performance vorzugaukeln, hat sich Apple nämlich entschieden, POST-Requests (z.B. per Ajax) im Browser zu cachen, wenn dies nicht explizit vom Server deaktiviert wird.

Apple steht damit ziemlich alleine … alle HTTP-Clients machen das aus gutem Grund nicht. In der “Restful HTTP”-Philosophie sind POST-Requests per Definition nicht idempotent, d.h. das Ergebnis mehrerer identischer POST-Requests an dieselbe URL selbst mit derselben Payload haben NICHT immer dasselbe Ergebnis. In SQL entspricht ein POST-Requests einem INSERT. Es werden also im Regelfall für jeden Request neue Datensätze angelegt.

POST-Requests zu cachen verbietet sich also, ausser der Serverbetreiber aktiviert es explizit mittels der üblichen HTTP-Header zum Caching.

Zwar kann ich verstehen, wenn Apple so viele HTTP-Requests sparen möchte wie es geht, damit der Benutzer möglichst performante Webseiten präsentiert bekommt, aber hier übertreiben sie ganz eindeutig.

Wenn man das Problem einmal gefunden und identifiziert hat, lässt es sich zum Glück sehr schnell deaktivieren. Wir haben im Server nun einen ServletFilter (Java) implementiert, der in alle Responses von POST-Requests zur REST-Schnittstelle den HTTP-Header [highlight1]Cache-Control: no-cache[/highlight1] einbaut.

Wenn man über den Server keine Kontrolle hat und das nicht einbauen kann, kann man als Client-Entwickler auch eine zufällige Komponente in die URL einbauen, sodass die URL immer unterschiedlich ist und iOS6 die Requests zwar cached, aber durch die wechselnde URL der Cache ins Leere läuft. Am besten geht das mit einem Timestamp:

url = url + "?" + (new Date()).getTime();

Der URL wird dann die Anzahl der Millisekunden seit 1970 angehangen.

Leave a Reply

Your email address will not be published. Required fields are marked *

*