La memorizzazione nella cache inaspettata di AJAX risulta in IE8


135

Sto riscontrando un serio problema con i risultati della memorizzazione nella cache di Internet Explorer da una richiesta Ajax di JQuery.

Ho un'intestazione sulla mia pagina Web che viene aggiornata ogni volta che un utente accede a una nuova pagina. Una volta caricata la pagina, lo faccio

$.get("/game/getpuzzleinfo", null, function(data, status) {
    var content = "<h1>Wikipedia Maze</h1>";
    content += "<p class='endtopic'>Looking for <span><a title='Opens the topic you are looking for in a separate tab or window' href='" + data.EndTopicUrl + "' target='_blank'>" + data.EndTopic + "<a/></span></p>";
    content += "<p class='step'>Step <span>" + data.StepCount + "</span></p>";
    content += "<p class='level'>Level <span>" + data.PuzzleLevel.toString() + "</span></p>";
    content += "<p class='startover'><a href='/game/start/" + data.PuzzleId.toString() + "'>Start Over</a></p>";

    $("#wikiheader").append(content);

}, "json");

Inietta semplicemente le informazioni dell'intestazione nella pagina. Puoi verificarlo andando su www.wikipediamaze.com e quindi effettuando il login e avviando un nuovo puzzle.

In ogni browser che ho testato (Google Chrome, Firefox, Safari, Internet Explorer) funziona benissimo tranne in IE. Tutto viene iniettato bene in IE la prima volta, ma dopo non effettua nemmeno la chiamata /game/getpuzzleinfo. È come se avesse memorizzato nella cache i risultati o qualcosa del genere.

Se cambio la chiamata a $.post("/game/getpuzzleinfo", ...Internet Explorer, la rispondo bene. Ma poi Firefox smette di funzionare.

Qualcuno può far luce su questo sul motivo per cui IE sta memorizzando nella cache le mie $.getchiamate Ajax?

AGGIORNARE

Per il suggerimento seguente, ho modificato la mia richiesta Ajax in questo, che ha risolto il mio problema:

$.ajax({
    type: "GET",
    url: "/game/getpuzzleinfo",
    dataType: "json",
    cache: false,
    success: function(data) { ... }
});

8
Grazie per averlo chiesto. Sono senza parole che questo comportamento del browser.
giovedì

1
Bella domanda e sito davvero interessante. Buona idea.
MikeMurko,

Risposte:


177

IE è noto per la sua aggressiva memorizzazione nella cache delle risposte Ajax. Mentre usi jQuery, puoi impostare un'opzione globale:

$.ajaxSetup({
    cache: false
});

che farà sì che jQuery aggiunga un valore casuale alla stringa di query della richiesta, evitando così che IE memorizzi nella cache la risposta.

Nota che se hai altre chiamate Ajax in corso dove desideri memorizzare nella cache, questo lo disabiliterà anche per quelle. In tal caso, passare all'utilizzo del metodo $ .ajax () e abilitare tale opzione esplicitamente per le richieste necessarie.

Vedi http://docs.jquery.com/Ajax/jQuery.ajaxSetup per maggiori informazioni.


1
Puoi anche aggiungere un timestamp alla fine dei tuoi URL. Non so perché jQuery non segua questo approccio.
Eric Johnson,

14
@Eric: questo è ciò che jQuery fa internamente: l'opzione "cache: false" gli dice solo di farlo.
NickFitz,

Perché jquery non lo ha attivato per impostazione predefinita?
speedplane il

Ho appena notato che le opzioni della cache non funzionano quando si tenta di richiedere la homepage in IE 8, con una chiamata a /. Modificalo in /index.phpo qualunque sia l'URL completo. O aggiungi tu stesso alcuni parametri falsi come/?f=f
Hugo Delsing,

8

Come menzionato da marr75 , GETviene memorizzato nella cache.

Ci sono un paio di modi per combattere questo. Oltre a modificare l'intestazione della risposta, puoi anche aggiungere una variabile di stringa di query generata casualmente alla fine dell'URL di destinazione. In questo modo, IE penserà che si tratti di un URL diverso ogni volta che viene richiesto.

Esistono diversi modi per farlo (come l'utilizzo Math.random(), una variazione della data, ecc.).

Ecco un modo per farlo:

var oDate = new Date();
var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds();
$.get(sURL, null, function(data, status) {
    // your work
});

3

Ottiene sempre la cache. Una strategia che potrebbe funzionare è quella di modificare l'intestazione della risposta e dire al client di non memorizzare nella cache le informazioni o di far scadere la cache molto presto.


Sembra una buona idea. Come potrei farlo?
Michea il

1
Questa è una domanda caricata, dipende dal codice lato server. Vedi la voce di Wikipedia "Elenco delle intestazioni HTTP" per una piccola guida. Esempi: Cache-Control: no-cache Scadenza: Gio, 01 Dic 1994 16:00:00 GMT Fondamentalmente è necessario aggiungere queste intestazioni di risposta alla risposta http. È abbastanza semplice in ASP.NET, Ruby e PHP. Basta cercare la lingua lato server in uso + modificare le intestazioni di risposta.
marr75,

3
Inoltre, e questa non è affatto una critica a Jquery (adoro quella libreria), il metodo per aggiungere un parametro di stringa di query casuale è sicuro ma scortese per il client (può lasciarli trattenere su elementi nella cache che non verranno mai utilizzati ancora).
marr75,

2

Se stai chiamando la pagina ashx puoi anche disabilitare la memorizzazione nella cache sul server con il seguente codice:

context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 

1

questo è quello che faccio per le chiamate Ajax:

var url = "/mypage.aspx";
// my other vars i want to add go here
url = url + "&sid=" + Math.random();
// make ajax call

funziona abbastanza bene per me.


1

NickFitz fornisce una buona risposta, ma dovrai disattivare anche la memorizzazione nella cache in IE9. Al fine di indirizzare solo IE8 e IE9 potresti farlo;

<!--[if lte IE 9]>
<script>
    $.ajaxSetup({
        cache: false
    });
</script>
<![endif]-->

0

Le risposte qui sono molto utili per coloro che usano jQuery o per qualche ragione usano direttamente l'oggetto xmlHttpRequest ...

Se si utilizza il proxy del servizio Microsoft generato automaticamente, non è così semplice da risolvere.

Il trucco è utilizzare il metodo Sys.Net.WebRequestManager.add_invokingRequest nel gestore eventi per modificare l'URL della richiesta:

networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + '&nocache=' + new Date().getMilliseconds(); 

Ho scritto un blog su questo: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/


0

Ho appena scritto un blog su questo esatto problema usando solo ExtJS ( http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )

Il problema era che stavo usando uno specifico formato di riscrittura dell'URL che non potevo usare i parametri convenzionali della stringa di query (? Param = valore), quindi avrei dovuto scrivere il parametro busting della cache come variabile postata invece ..... Avrei pensato che l'uso delle variabili POST è un po 'più sicuro di GET, semplicemente perché molti framework MVC usano il modello

protocollo: // host / controllore / action / param1 / param2

e quindi la mappatura del nome della variabile sul valore viene persa e i parametri vengono semplicemente impilati ... quindi quando si utilizza un parametro GET cache buster

cioè protocollo: // host / controller / action / param1 / param2 / no_cache122300201

no_cache122300201 può essere scambiato per un parametro $ param3 che potrebbe avere un valore predefinito

vale a dire

azione di funzione pubblica ($ param1, $ param2, $ param3 = "valore predefinito") {//..//}

nessuna possibilità che ciò accada con i buster della cache POSTATI


0

Se si utilizza ASP.NET MVC, è sufficiente aggiungere questa riga in cima all'azione del controller:

[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{

}

Il comportamento in questione è sul lato browser; questa risposta si riferisce alla memorizzazione nella cache sul lato server.
Mark Sowul,

@MarkSowul Outputcache ha 3 opzioni Client, Server e qualsiasi. IE utilizza OutputCache come predefinito qualsiasi che va principalmente come cache lato client. Puoi vedere maggiori dettagli qui dougwilsonsa.wordpress.com/2011/04/29/…
batmaci

@MarkSowul puoi anche vedere la domanda e la risposta correlate qui. Pensi che questo sia anche sul lato server? stackoverflow.com/questions/2653092/...
batmaci

1
Sì, scusa, hai ragione: non avevo capito che la tua risposta può influire sia sulla cache lato server sia su quella lato client.
Mark Sowul,

-1

IE ha il diritto di eseguire questa memorizzazione nella cache; per garantire che l'elemento non sia memorizzato nella cache, le intestazioni devono essere impostate di conseguenza.

Se si utilizza ASP.NET MVC, è possibile scrivere un ActionFilter; dentro OnResultExecuted, controlla filterContext.HttpContext.Request.IsAjaxRequest(). In tal caso, imposta l'intestazione di scadenza della risposta:filterContext.HttpContext.Response.Expires = -1;

Secondo http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ :

Alcune persone preferiscono usare l'intestazione Cache - Control: no - cache invece che scade. Ecco la differenza:
Cache-Control: no-cache - assolutamente NO cache
scade: -1 - il browser "di solito" contatta il server Web per gli aggiornamenti a quella pagina tramite una richiesta condizionale If-Modified-Since. Tuttavia, la pagina rimane nella cache del disco e viene utilizzata in situazioni appropriate senza contattare il server Web remoto, ad esempio quando i pulsanti BACK e FORWARD vengono utilizzati per accedere alla cronologia di navigazione o quando il browser è in modalità offline.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.