Seit dem Upgrade auf iOS 6 können wir in der Webansicht von Safari $.ajax
Anrufe zwischenspeichern. Dies erfolgt im Kontext einer PhoneGap-Anwendung, sodass Safari WebView verwendet wird. Unsere $.ajax
Aufrufe sind POST
Methoden und wir haben den Cache auf false gesetzt {cache:false}
, aber dies geschieht immer noch. Wir haben versucht TimeStamp
, den Headern manuell ein hinzuzufügen , 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 etwas heißt:
getNewRecordID(intRecordType)
Diese Funktion empfängt immer wieder dieselben Eingabeparameter, aber die zurückgegebenen Daten sollten jedes Mal anders sein.
Muss in Apples Eile sein, um iOS 6 eindrucksvoll mitzumachen. Sie waren zu zufrieden mit den Cache-Einstellungen. Hat jemand anderes dieses Verhalten unter iOS 6 gesehen? Wenn ja, was genau verursacht es?
Die Problemumgehung bestand darin, die Funktionssignatur so zu ändern:
getNewRecordID(intRecordType, strTimestamp)
und übergeben Sie dann immer auch einen TimeStamp
Parameter und verwerfen Sie diesen Wert einfach auf der Serverseite. Dies umgeht das Problem. Ich hoffe, das hilft einer anderen armen Seele, die wie ich 15 Stunden mit diesem Thema verbringt!
quelle
Antworten:
Nach einigem Nachforschen stellt sich heraus, dass Safari unter iOS6 POSTs zwischenspeichert, die entweder keine Cache-Control-Header oder sogar "Cache-Control: max-age = 0" haben.
Die einzige Möglichkeit, zu verhindern, dass dieses Caching auf globaler Ebene stattfindet, anstatt zufällige Abfrageringe am Ende von Serviceaufrufen hacken zu müssen, besteht darin, "Cache-Control: no-cache" festzulegen.
Damit:
Ich vermute, dass Apple dies aus der HTTP-Spezifikation in Abschnitt 9.5 über POST nutzt:
Theoretisch können Sie also POST-Antworten zwischenspeichern ... wer wusste. Aber noch kein anderer Browserhersteller hat jemals gedacht, dass dies eine gute Idee wäre. Dies berücksichtigt jedoch NICHT das Caching, wenn keine Cache-Control- oder Expires-Header gesetzt sind, sondern nur, wenn einige gesetzt sind. Es muss also ein Fehler sein.
Im Folgenden wird beschrieben, was ich im rechten Teil meiner Apache-Konfiguration verwende, um auf die gesamte API abzuzielen, da ich in diesem Fall eigentlich nichts zwischenspeichern möchte, auch nicht. Was ich nicht weiß, ist, wie man dies nur für POSTs einstellt.
Update: Ich habe gerade bemerkt, dass ich nicht darauf hingewiesen habe, dass dies nur dann der Fall ist, wenn der POST identisch 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 paar POST-Daten hinzufügen.
Update: Sie können den "No-Cache" nur auf POSTs beschränken, wenn Sie dies in Apache wünschen:
quelle
Ich hoffe, dass dies für andere Entwickler von Nutzen sein kann, die ihren Kopf gegen die Wand schlagen. Ich habe festgestellt, dass eine der folgenden Möglichkeiten Safari unter iOS 6 daran hindert, die POST-Antwort zwischenzuspeichern:
Meine Lösung war die folgende in meinem Javascript (alle meine AJAX-Anfragen sind POST).
Außerdem füge ich vielen meiner Serverantworten den Header [pragma: no-cache] hinzu.
Wenn Sie die oben genannte Lösung verwenden, beachten Sie, dass alle von Ihnen getätigten Aufrufe von $ .ajax (), die auf global: false festgelegt sind, NICHT die in $ .ajaxSetup () angegebenen Einstellungen verwenden. Daher müssen Sie die Header erneut hinzufügen.
quelle
Einfache Lösung für alle Ihre Webdienstanforderungen, vorausgesetzt, Sie verwenden jQuery:
Weitere Informationen zum jQuery-Vorfilteraufruf finden Sie hier .
Wenn Sie jQuery nicht verwenden, überprüfen Sie die Dokumente für die Bibliothek Ihrer Wahl. Sie können ähnliche Funktionen haben.
quelle
Ich hatte gerade dieses Problem auch in einer PhoneGap- Anwendung. Ich habe es mithilfe der JavaScript-Funktion
getTime()
folgendermaßen gelöst :Ich habe ein paar Stunden damit verbracht, das herauszufinden. Es wäre nett von Apple gewesen, Entwickler über dieses Caching-Problem zu informieren.
quelle
{cache:false}
als Option für entweder$.post()
oder kommentieren$.ajaxSetup()
, aber laut den Dokumenten werden diese Argumente ignoriert. jQuery wird Post-Anfragen niemals zwischenspeichern, berücksichtigt jedoch nicht den Browser. Vielleicht wäre eine bessere Option, Anfragen mit einen Zeitstempel hinzuzufügen$.ajaxPrefilter()
.function send_ajax(my_data,refresh)
. SieheIch hatte das gleiche Problem mit einer Webanwendung, die Daten vom ASP.NET-Webservice abruft
Das hat bei mir funktioniert:
quelle
Endlich habe ich eine Lösung für mein Upload-Problem.
In JavaScript:
In PHP :
quelle
Aus meinem eigenen Blog-Beitrag iOS 6.0, in dem Ajax-POST-Anfragen zwischengespeichert werden :
So beheben Sie das Problem: Es gibt verschiedene Methoden, um das Zwischenspeichern von Anforderungen 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:
ZeptoJS:
Suchen Sie nach iOS 6.0 und setzen Sie den Ajax-Header wie folgt:
Serverseite
Java:
Stellen Sie sicher, dass Sie dies oben auf der Seite hinzufügen, bevor Daten an den Client gesendet werden.
.NETZ
Oder
PHP
quelle
Dieses JavaScript-Snippet funktioniert hervorragend mit jQuery und jQuery Mobile:
Platzieren Sie es einfach irgendwo in Ihrem JavaScript-Code (nachdem jQuery geladen wurde und am besten, bevor Sie AJAX-Anforderungen ausführen), und es sollte helfen.
quelle
Sie können dieses Problem auch beheben, indem Sie die AjQ- Funktion von jQuery ändern , indem Sie Folgendes (ab 1.7.1) oben in der Ajax-Funktion ausführen (Funktion beginnt in Zeile 7212). Diese Änderung aktiviert die integrierte Anti-Cache-Funktion von jQuery für alle POST-Anforderungen.
(Das vollständige Skript finden Sie unter
http://dl.dropbox.com/u/58016866/jquery-1.7.1.js
.)Fügen Sie unter Zeile 7221 ein:
Ändern Sie dann Folgendes (beginnend mit Zeile ~ 7497).
Zu:
quelle
jQuery.ajaxPrefiler
Ihre Ajax-Anfrage direkt vor dem Erstellen ändern. Sie können dasselbe mit optimiertem und aktualisiertem sicherem Code archivieren.Eine schnelle Lösung für GWT-RPC-Dienste besteht darin, dies allen Remote-Methoden hinzuzufügen:
quelle
Dies ist ein Update der Antwort von Baz1nga. Da
options.data
es sich nicht um ein Objekt, sondern um eine Zeichenfolge handelt, habe ich nur auf die Verkettung des Zeitstempels zurückgegriffen:quelle
Um dieses Problem für WebApps zu beheben, die dem Startbildschirm hinzugefügt wurden, müssen die beiden am häufigsten bewerteten Problemumgehungen befolgt werden. Das Caching muss auf dem Webserver deaktiviert werden, um zu verhindern, dass neue Anforderungen in Zukunft zwischengespeichert werden, und jeder Post-Anforderung müssen zufällige Eingaben hinzugefügt werden, damit bereits zwischengespeicherte Anforderungen durchlaufen werden. Bitte beziehen Sie sich auf meinen Beitrag:
iOS6 - Gibt es eine Möglichkeit, zwischengespeicherte Ajax-POST-Anforderungen für Webanwendungen zu löschen, die dem Startbildschirm hinzugefügt wurden?
WARNUNG: Für alle, die eine Problemumgehung implementiert haben, indem sie ihren Anforderungen einen Zeitstempel hinzugefügt haben, ohne das Caching auf dem Server zu deaktivieren. Wenn Ihre App zum Startbildschirm hinzugefügt wird, wird JEDE Antwort nach dem Posting zwischengespeichert. Wenn Sie den Safari-Cache löschen, wird sie nicht gelöscht und scheint nicht abzulaufen. Wenn nicht jemand eine Möglichkeit hat, dies zu beheben, scheint dies ein potenzieller Speicherverlust zu sein!
quelle
Dinge, die mit einem iPad 4 / iOS 6 für mich NICHT funktioniert haben :
Meine Anfrage enthält: Cache-Control: kein Cache
Cache hinzufügen: false für meinen jQuery-Ajax-Aufruf
Nur das hat den Trick gemacht:
quelle
$.ajax
cache: false
Hängt ab 2017 die URL an den Abfrageparameter an_=Date.prototype.getTime()
, sodass das manuelle Anhängen des Zeitstempels nicht mehr erforderlich sein sollte.Das ist die Lösung für GWT-RPC
quelle
Meine Problemumgehung in ASP.NET (Pagemethoden, Webservice usw.)
quelle
Das Hinzufügen von Cache-Buster-Parametern, um die Anforderung anders aussehen zu lassen, scheint eine solide Lösung zu sein. Ich würde jedoch davon abraten, da dies jeder Anwendung schaden würde, die auf dem tatsächlichen Caching beruht. Es ist die bestmögliche Lösung, wenn die APIs die richtigen Header ausgeben, auch wenn dies etwas schwieriger ist als das Hinzufügen von Cache-Bustern zu den Anrufern.
quelle
Für diejenigen, die verwenden
Struts 1
, ist hier, wie ich das Problem behoben habe.web.xml
com.example.struts.filters.CacheControlFilter.js
quelle
Ich konnte mein Problem beheben, indem ich eine Kombination aus $ .ajaxSetup verwendete und einen Zeitstempel an die URL meines Posts anhängte (nicht an die Post-Parameter / den Post-Body). Dies basiert auf den Empfehlungen früherer Antworten
quelle
Ich denke, Sie haben Ihr Problem bereits gelöst, aber lassen Sie mich eine Idee zum Web-Caching teilen.
Es ist wahr, dass Sie viele Header in jeder Sprache hinzufügen können, die Sie verwenden, serverseitig, clientseitig, und Sie können viele andere Tricks verwenden, um Web-Caching zu vermeiden, aber denken Sie immer, dass Sie nie wissen können, von wo aus der Client eine Verbindung zu Ihrem Server herstellt. Sie wissen nie, ob er eine Hotel-Hot-Spot-Verbindung verwendet, die Squid oder andere Caching-Produkte verwendet.
Wenn die Benutzer Proxy verwenden, um seine reale Position zu verbergen, usw.… die reale einzige Weg , um zu vermeiden Caching ist der Zeitstempel in der Anfrage auch wenn sie nicht benutzt wird.
Zum Beispiel:
Dann hat nicht jeder Cache-Manager, den Sie übergeben müssen, dieselbe URL im Cache-Repository gefunden und den Seiteninhalt erneut heruntergeladen.
quelle
$.ajax
Option festlegen und diese festlegen,{cache:false}
fügt jQuery selbst automatisch einen Cache-Busting hinzu hinter den Kulissen, ohne dass Sie jemals etwas anderes tun müssen.Abhängig von der App können Sie das Problem jetzt in iOS 6 mithilfe von Safari> Erweitert> Web Inspector beheben, sodass dies in dieser Situation hilfreich ist.
Schließen Sie das Telefon auf einem Mac an Safari an und verwenden Sie das Entwicklermenü, um Probleme mit der Web-App zu beheben.
Löschen Sie die Website-Daten auf dem iPhone nach dem Update auf iOS6, auch für die App, mithilfe einer Webansicht. Nur eine App hatte ein Problem und dies löste es während des IOS6 Beta-Tests vor langer Zeit, seitdem keine wirklichen Probleme mehr.
Möglicherweise müssen Sie sich auch Ihre App ansehen und NSURLCache in einer WebView in einer benutzerdefinierten App auschecken.
https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSURLCache_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003754
Ich denke, abhängig von der wahren Natur Ihres Problems, der Implementierung usw.
Ref: $ .ajax ruft an
quelle
Ich habe eine Problemumgehung gefunden, die mich neugierig macht, warum es funktioniert. Bevor ich Tadejs Antwort zum ASP.NET-Webdienst las, versuchte ich, etwas zu finden, das funktionieren würde.
Und ich sage nicht, dass es eine gute Lösung ist, aber ich wollte es nur hier dokumentieren.
Hauptseite: Enthält eine JavaScript-Funktion, checkStatus (). Die Methode ruft eine andere Methode auf, die einen jQuery AJAX-Aufruf verwendet, um den HTML-Inhalt zu aktualisieren. Ich habe setInterval verwendet, um checkStatus () aufzurufen. Natürlich bin ich auf das Caching-Problem gestoßen.
Lösung: Verwenden Sie eine andere Seite, um das Update aufzurufen.
Auf der Hauptseite habe ich eine boolesche Variable, runUpdate, festgelegt und dem Body-Tag Folgendes hinzugefügt:
In der von helper.html:
Wenn checkStatus () von der Hauptseite aufgerufen wird, erhalte ich den zwischengespeicherten Inhalt. Wenn ich checkStatus von der untergeordneten Seite aus aufrufe, erhalte ich aktualisierte Inhalte.
quelle
Während meine Anmelde- und Anmeldeseiten in Firefox, IE und Chrome wie ein Zauber wirken ... Ich habe in Safari für IOS und OSX mit diesem Problem zu kämpfen. Vor einigen Monaten habe ich eine Problemumgehung für SO gefunden.
ODER über Javascript
Das ist ein bisschen hässlich, funktioniert aber eine Weile.
Ich weiß nicht warum, aber wenn ich null auf das
onunload
Ereignis zurückgib, wird die Seite in Safari nicht zwischengespeichert.quelle
Wir haben festgestellt, dass ältere iPhones und iPads, auf denen die iOS-Versionen 9 und 10 ausgeführt werden, gelegentlich falsche AJAX-Ergebnisse liefern, möglicherweise aufgrund der Verringerung der CPU-Geschwindigkeit durch Apple. Bei der Rückgabe des leeren Ergebnisses ruft iOS den Server nicht so auf, als würde ein Ergebnis aus dem Cache zurückgegeben. Die Häufigkeit variiert stark und liegt zwischen 10% und 30% der AJAX-Anrufe.
Die Lösung ist kaum zu glauben. Warten Sie einfach 1s und rufen Sie erneut an. In unseren Tests war nur eine Wiederholung alles, was jemals benötigt wurde, aber wir haben den Code geschrieben, um bis zu viermal aufzurufen. Wir sind uns nicht sicher, ob die Wartezeit von 1 Sekunden erforderlich ist, aber wir wollten nicht riskieren, unseren Server mit wiederholten Anrufen zu belasten.
Wir haben festgestellt, dass das Problem bei zwei verschiedenen AJAX-Aufrufen aufgetreten ist, bei denen verschiedene API-Dateien mit unterschiedlichen Daten aufgerufen wurden. Aber ich mache mir Sorgen, dass es bei jedem AJAX-Anruf passieren könnte. Wir wissen es einfach nicht, weil wir nicht jedes AJAX-Ergebnis überprüfen und nicht jeden Anruf mehrmals auf alten Geräten testen.
Beide Problem-AJAX-Aufrufe verwendeten: POST, Asynchron = true, setRequestHeader = ('Content-Type', 'application / x-www-form-urlencoded')
Wenn das Problem auftritt, wird normalerweise nur ein AJAX-Anruf ausgeführt. Es liegt also nicht an überlappenden AJAX-Aufrufen. Manchmal tritt das Problem auf, wenn das Gerät ausgelastet ist, aber manchmal nicht, und ohne DevTools wissen wir nicht wirklich, was gerade passiert.
iOS 13 tut dies nicht, Chrome oder Firefox nicht. Wir haben keine Testgeräte mit iOS 11 oder 12. Vielleicht könnte jemand anderes diese testen?
Ich stelle dies hier fest, da diese Frage das beste Google-Ergebnis bei der Suche nach diesem Problem ist.
quelle
Es funktionierte mit ASP.NET erst, nachdem der
pragma:no-cache
Header in IIS hinzugefügt wurde .Cache-Control: no-cache
war nicht genug.quelle
Ich schlage eine Problemumgehung vor, um die Funktionssignatur so zu ändern:
getNewRecordID (intRecordType, strTimestamp) und übergeben Sie dann immer auch einen TimeStamp-Parameter und verwerfen Sie diesen Wert einfach auf der Serverseite. Dies umgeht das Problem.
quelle