1101 Stimmen

Legt Safari unter iOS 6 $.ajax-Ergebnisse zwischen?

Seit dem Upgrade auf iOS 6 nimmt sich die Webansicht von Safari die Freiheit, zwischenzuspeichern $.ajax ruft. Dies geschieht im Kontext einer PhoneGap-Anwendung, die also die Safari WebView verwendet. Unser $.ajax Anrufe sind POST Methoden und wir haben den Cache auf false gesetzt {cache:false} aber das Problem tritt immer noch auf. Wir haben versucht, manuell eine TimeStamp zu den Kopfzeilen hinzugefügt, aber das hat nicht geholfen.

Wir haben weitere Nachforschungen angestellt und festgestellt, dass Safari nur bei Webdiensten mit einer statischen Funktionssignatur, die sich von Aufruf zu Aufruf nicht ändert, Ergebnisse aus dem Cache zurückgibt. Stellen Sie sich zum Beispiel eine Funktion vor, die etwa so heißt:

getNewRecordID(intRecordType)

Diese Funktion erhält immer wieder dieselben Eingabeparameter, aber die Daten, die sie zurückgibt, sollten jedes Mal anders sein.

In der Eile, mit der Apple iOS 6 zum Laufen bringen wollte, haben sie sich wohl zu sehr mit den Cache-Einstellungen begnügt. Hat noch jemand dieses Verhalten bei iOS 6 beobachtet? Wenn ja, was genau ist die Ursache?


Die Abhilfe, die wir gefunden haben, besteht darin, die Funktionssignatur so zu ändern, dass sie etwa so aussieht:

getNewRecordID(intRecordType, strTimestamp)

und geben Sie dann immer eine TimeStamp und verwerfen Sie diesen Wert einfach auf der Serverseite. Auf diese Weise lässt sich das Problem umgehen.

25voto

goker Punkte 2630

Endlich habe ich eine Lösung für mein Problem beim Hochladen.

In JavaScript:

var xhr = new XMLHttpRequest();
xhr.open("post", 'uploader.php', true);
xhr.setRequestHeader("pragma", "no-cache");

En PHP :

header('cache-control: no-cache');

16voto

kiranvj Punkte 26968

Aus meinem eigenen Blogbeitrag iOS 6.0 Zwischenspeicherung von Ajax POST-Anfragen :

Wie man das beheben kann: Es gibt verschiedene Methoden, um das Zwischenspeichern von Anfragen zu verhindern. Die empfohlene Methode ist das Hinzufügen eines no-cache-Headers. So wird es gemacht.

jQuery:

Prüfen Sie, ob iOS 6.0 verfügbar ist und setzen Sie den Ajax-Header wie folgt:

$.ajaxSetup({ cache: false });

ZeptoJS:

Prüfen Sie, ob iOS 6.0 verfügbar ist und setzen Sie den Ajax-Header wie folgt:

$.ajax({
    type: 'POST',
    headers : { "cache-control": "no-cache" },
    url : ,
    data:,
    dataType : 'json',
    success : function(responseText) {…}

Server-Seite

Java:

httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");

Stellen Sie sicher, dass dies am Anfang der Seite hinzugefügt wird, bevor Daten an den Kunden gesendet werden.

.NET

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.

8voto

Jonathan Punkte 6310

Dieses JavaScript-Snippet funktioniert hervorragend mit jQuery und jQuery Mobile:

$.ajaxSetup({
    cache: false,
    headers: {
        'Cache-Control': 'no-cache'
    }
});

Platzieren Sie es einfach irgendwo in Ihrem JavaScript-Code (nachdem jQuery geladen ist, und am besten bevor Sie AJAX-Anfragen stellen) und es sollte helfen.

7voto

Sam Shiles Punkte 9419

Sie können dieses Problem auch beheben, indem Sie die jQuery Ajax Funktion, indem Sie (ab 1.7.1) am Anfang der Ajax-Funktion (die Funktion beginnt in Zeile 7212) folgendes tun. Durch diese Änderung wird die integrierte Anti-Cache-Funktion von jQuery für alle POST-Anfragen aktiviert.

(Das vollständige Skript ist verfügbar unter http://dl.dropbox.com/u/58016866/jquery-1.7.1.js .)

Unterhalb von Zeile 7221 einfügen:

if (options.type === "POST") {
    options.cache = false;
}

Ändern Sie dann Folgendes (ab Zeile ~7497).

if (!s.hasContent) {
    // If data is available, append data to URL
    if (s.data) {
        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
        // #9682: remove data so that it's not used in an eventual retry
        delete s.data;
    }

    // Get ifModifiedKey before adding the anti-cache parameter
    ifModifiedKey = s.url;

    // Add anti-cache in URL if needed
    if (s.cache === false) {
        var ts = jQuery.now(),
        // Try replacing _= if it is there
        ret = s.url.replace(rts, "$1_=" + ts);

        // If nothing was replaced, add timestamp to the end.
        s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
    }
}

An:

// More options handling for requests with no content
if (!s.hasContent) {
    // If data is available, append data to URL
    if (s.data) {
        s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
        // #9682: remove data so that it's not used in an eventual retry
        delete s.data;
    }

    // Get ifModifiedKey before adding the anti-cache parameter
    ifModifiedKey = s.url;
}

// Add anti-cache in URL if needed
if (s.cache === false) {
    var ts = jQuery.now(),
    // Try replacing _= if it is there
    ret = s.url.replace(rts, "$1_=" + ts);

    // If nothing was replaced, add timestamp to the end.
    s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
}

6voto

remcoder Punkte 192

Dies ist eine Aktualisierung der Antwort von Baz1nga. Seit options.data kein Objekt, sondern eine Zeichenkette ist, habe ich den Zeitstempel einfach aneinandergereiht:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  if (originalOptions.type == "post" || options.type == "post") {

    if (options.data && options.data.length)
      options.data += "&";
    else
      options.data = "";

    options.data += "timeStamp=" + new Date().getTime();
  }
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X