
Benutzer1684978
Seit dem Upgrade auf iOS 6 sehen wir, dass sich die Webansicht von Safari die Freiheit des Cachings nimmt $.ajax
Anrufe. Dies steht im Kontext einer PhoneGap-Anwendung, also wird Safari WebView verwendet. Unsere $.ajax
Anrufe sind POST
Methoden und wir haben den Cache auf false gesetzt {cache:false}
, aber das passiert immer noch. Wir haben versucht, a manuell hinzuzufügen TimeStamp
zu den Headern, aber es hat nicht geholfen.
Wir haben weitere Nachforschungen angestellt und festgestellt, dass Safari nur zwischengespeicherte Ergebnisse für Webdienste zurückgibt, deren Funktionssignatur statisch ist und sich nicht von Aufruf zu Aufruf ändert. Stellen Sie sich zum Beispiel eine Funktion vor, die so heißt:
getNewRecordID(intRecordType)
Diese Funktion erhält immer wieder die gleichen Eingabeparameter, aber die zurückgegebenen Daten sollten jedes Mal anders sein.
Muss in Apples Eile sein, iOS 6 beeindruckend zum Laufen zu bringen, sie waren mit den Cache-Einstellungen zu zufrieden. Hat jemand anderes dieses Verhalten auf iOS 6 gesehen? Wenn ja, woran genau liegt es?
Die Problemumgehung, die wir gefunden haben, bestand darin, die Funktionssignatur so zu ändern:
getNewRecordID(intRecordType, strTimestamp)
und dann immer in a übergehen TimeStamp
-Parameter und verwerfen Sie diesen Wert einfach auf der Serverseite. Dies umgeht das Problem.

Kieran
Nach ein wenig Nachforschung stellt sich heraus, dass Safari auf iOS6 POSTs zwischenspeichert, die entweder keine Cache-Control-Header oder sogar “Cache-Control: max-age=0” haben.
Die einzige Möglichkeit, die ich gefunden habe, um zu verhindern, dass dieses Caching auf globaler Ebene stattfindet, anstatt zufällige Abfragezeichenfolgen am Ende von Dienstaufrufen zu hacken, besteht darin, “Cache-Control: no-cache” festzulegen.
Damit:
- Keine Cache-Control- oder Expires-Header = iOS6 Safari wird zwischengespeichert
- Cache-Control max-age=0 und ein sofortiges Expires = iOS6 Safari wird cachen
- Cache-Steuerung: no-cache = iOS6 Safari wird NICHT cachen
Ich vermute, dass Apple dies aus der HTTP-Spezifikation in Abschnitt 9.5 über POST ausnutzt:
Antworten auf diese Methode können nicht zwischengespeichert werden, es sei denn, die Antwort enthält entsprechende Cache-Control- oder Expires-Header-Felder. Die Antwort 303 (See Other) kann jedoch verwendet werden, um den Benutzeragenten anzuweisen, eine zwischenspeicherbare Ressource abzurufen.
Theoretisch können Sie also POST-Antworten zwischenspeichern … wer hätte das gedacht. Aber kein anderer Browser-Hersteller hat bisher jemals daran gedacht, dass dies eine gute Idee wäre. Dies berücksichtigt jedoch NICHT das Caching, wenn keine Cache-Control- oder Expires-Header festgelegt sind, sondern nur, wenn einige festgelegt sind. Es muss also ein Bug sein.
Unten ist, was ich im rechten Teil meiner Apache-Konfiguration verwende, um auf die gesamte API abzuzielen, da ich tatsächlich nichts zwischenspeichern möchte, auch nicht. Was ich nicht weiß, ist, wie man das nur für POSTs einstellt.
Header set Cache-Control "no-cache"
Update: Ich habe gerade bemerkt, dass ich nicht darauf hingewiesen habe, dass dies nur der Fall ist, wenn der POST gleich ist. Ändern Sie also die POST-Daten oder die URL, und es geht Ihnen gut. Sie können also, wie an anderer Stelle erwähnt, einfach einige zufällige Daten zur URL oder ein bisschen POST-Daten hinzufügen.
Update: Sie können den “No-Cache” nur auf POSTs beschränken, wenn Sie dies in Apache wünschen:
SetEnvIf Request_Method "POST" IS_POST
Header set Cache-Control "no-cache" env=IS_POST
Ich hoffe, dass dies für andere Entwickler von Nutzen sein kann, die hier ihren Kopf gegen die Wand schlagen. Ich habe festgestellt, dass eines der folgenden Dinge verhindert, dass Safari unter iOS 6 die POST-Antwort zwischenspeichert:
- Hinzufügen [cache-control: no-cache] in den Request-Headern
- Hinzufügen eines variablen URL-Parameters wie der aktuellen Uhrzeit
- Hinzufügen [pragma: no-cache] in den Antwortheadern
- Hinzufügen [cache-control: no-cache] in den Antwortheadern
Meine Lösung war die folgende in meinem Javascript (alle meine AJAX-Anfragen sind POST).
$.ajaxSetup({
type: 'POST',
headers: { "cache-control": "no-cache" }
});
Ich füge auch die hinzu [pragma: no-cache] Header zu vielen meiner Serverantworten.
Wenn Sie die obige Lösung verwenden, beachten Sie, dass alle von Ihnen getätigten $.ajax()-Aufrufe, die auf global: false gesetzt sind, NICHT die in $.ajaxSetup() angegebenen Einstellungen verwenden, sodass Sie die Header erneut hinzufügen müssen.

Baz1nga
Einfache Lösung für alle Ihre Webdienstanfragen, vorausgesetzt, Sie verwenden jQuery:
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
// you can use originalOptions.type || options.type to restrict specific type of requests
options.data = jQuery.param($.extend(originalOptions.data||{}, {
timeStamp: new Date().getTime()
}));
});
Lesen Sie mehr über den jQuery-Vorfilteraufruf Hier.
Wenn Sie jQuery nicht verwenden, überprüfen Sie die Dokumentation für die Bibliothek Ihrer Wahl. Sie können ähnliche Funktionen haben.

Bashevis
Ich hatte dieses Problem auch gerade in a PhoneGap Anwendung. Ich habe es mit der JavaScript-Funktion gelöst getTime()
auf folgende Art:
var currentTime = new Date();
var n = currentTime.getTime();
postUrl = "http://www.example.com/test.php?nocache="+n;
$.post(postUrl, callbackFunction);
Ich habe ein paar Stunden damit verschwendet, das herauszufinden. Es wäre nett von Apple gewesen, die Entwickler über dieses Caching-Problem zu informieren.
Ich hatte das gleiche Problem mit einer Webapp, die Daten vom ASP.NET-Webservice erhielt
Das hat bei mir funktioniert:
public WebService()
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
...
}
Endlich habe ich eine Lösung für mein Upload-Problem.
In JavaScript:
var xhr = new XMLHttpRequest();
xhr.open("post", 'uploader.php', true);
xhr.setRequestHeader("pragma", "no-cache");
Im PHP:
header('cache-control: no-cache');
Aus meinem eigenen Blogbeitrag iOS 6.0 speichert Ajax-POST-Anfragen:
So beheben Sie das Problem: Es gibt verschiedene Methoden, um das Caching von Anfragen zu verhindern. Die empfohlene Methode ist das Hinzufügen eines No-Cache-Headers. So wird es gemacht.
jQuery:
Suchen Sie nach iOS 6.0 und setzen Sie den Ajax-Header wie folgt:
$.ajaxSetup({ cache: false });
ZeptoJS:
Suchen Sie nach iOS 6.0 und setzen Sie den Ajax-Header wie folgt:
$.ajax({
type: 'POST',
headers : { "cache-control": "no-cache" },
url : ,
data:,
dataType : 'json',
success : function(responseText) {…}
Serverseitig
Java:
httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
Stellen Sie sicher, dass Sie dies oben auf der Seite hinzufügen, bevor Daten an den Client gesendet werden.
.NETZ
Response.Cache.SetNoStore();
Oder
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
PHP
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.
8668400cookie-checkZwischenspeichert Safari unter iOS 6 $.ajax-Ergebnisse?yes
Das ist absolut schockierend. Wir haben auch gerade ein paar Stunden damit verbracht, herauszufinden, was gerade nicht mehr funktioniert. Unser AJAX-Login, das einen POST durchführt (und Header hat, um auch das Caching zu verhindern), wird von Safari zwischengespeichert, sodass es einfach dasselbe JSON zurückgibt wie beim letzten Mal, ohne den Server überhaupt zu testen … unglaublich! Wir müssen einen Fix hacken, aber Sie sollten niemals einen POST zwischenspeichern, es ist verrückt.
– Kiran
20. September 2012 um 14:55 Uhr
Veröffentlichen Sie Ihre Lösung als Antwort und nicht als Aktualisierung der Frage.
– ChrisF
♦
21. September 2012 um 14:40 Uhr
POST-Anforderungen sind nicht idempotent, was bedeutet, dass sie nicht zwischengespeichert werden sollten wenn nicht die Antwort empfiehlt dies ausdrücklich über ihre Antwortheader.
– James M. Greene
21. September 2012 um 15:14 Uhr
Um Apple dazu zu bringen, dies zu beheben, melden Sie einen Fehler unter bugreport.apple.com. Ich habe das gleiche getan.
– Mathias Bynens
23. September 2012 um 10:13 Uhr
Mark Nottingham (Vorsitzender der IETF-HTTPbis-Arbeitsgruppe) hat heute einen interessanten Blogbeitrag darüber geschrieben: mnot.net/blog/2012/09/24/caching_POST
– Benjamin Brizzi
24. September 2012 um 15:02 Uhr