asp.net - El almacenamiento inesperado en caché de los resultados de AJAX en IE8
jquery internet-explorer (10)
Tengo un problema grave con los resultados del almacenamiento en caché de Internet Explorer a partir de una solicitud JQuery Ajax.
Tengo un encabezado en mi página web que se actualiza cada vez que un usuario navega a una página nueva. Una vez que la página está cargada, hago esto
$.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");
Simplemente inyecta información de encabezado en la página. Puede verificarlo yendo a www.wikipediamaze.com y luego iniciando sesión y comenzando un nuevo acertijo.
En cada navegador que he probado (Google Chrome, Firefox, Safari, Internet Explorer) funciona muy bien, excepto en IE. Eveything se inyecta muy bien en IE la primera vez, pero después de eso, ni siquiera hace la llamada a /game/getpuzzleinfo
. Es como si hubiera almacenado los resultados o algo así.
Si cambio la llamada a $.post("/game/getpuzzleinfo", ...
IE lo recoge bien, pero Firefox deja de funcionar.
¿Puede alguien arrojar algo de luz sobre esto en cuanto a por qué IE está almacenando en caché mis llamadas $.get
ajax?
ACTUALIZAR
Según la sugerencia a continuación, he cambiado mi solicitud de AJAX a esto, que solucionó mi problema:
$.ajax({
type: "GET",
url: "/game/getpuzzleinfo",
dataType: "json",
cache: false,
success: function(data) { ... }
});
Acabo de escribir un blog sobre este tema solo usando ExtJS ( http://thecodeabode.blogspot.com/2010/10/cache-busting-ajax-requests-in-ie.html )
El problema era que estaba usando un formato de reescritura de URL específico. No podía usar los parámetros de cadena de consulta convencionales (? Param = value), así que escribí el parámetro de prevención de caché como una variable publicada en su lugar ... Pensé que sí. que usar variables POST es un poco más seguro que GET, simplemente porque muchos frameworks MVC usan el patrón
protocolo: // host / controller / action / param1 / param2
y así se pierde la asignación del nombre de variable a valor, y los parámetros simplemente se apilan ... por lo tanto, cuando se utiliza un parámetro de bus caché GET
es decir, protocolo: // host / controller / action / param1 / param2 / no_cache122300201
no_cache122300201 se puede confundir con un parámetro $ param3 que podría tener un valor predeterminado
es decir
acción de función pública ($ param1, $ param2, $ param3 = "valor predeterminado") {//..//}
no hay posibilidad de que eso suceda con los buscadores de caché POSTED
Como marr75 mencionó, los GET
están en caché.
Hay un par de formas de combatir esto. Además de modificar el encabezado de respuesta, también puede agregar una variable de cadena de consulta generada aleatoriamente al final de la URL objetivo. De esta forma, IE creerá que es una URL diferente cada vez que se solicita.
Hay varias maneras de hacerlo (como usar Math.random()
, una variación en la fecha, etc.).
Aquí hay una forma de hacerlo:
var oDate = new Date();
var sURL = "/game/getpuzzleinfo?randomSeed=" + oDate.getMilliseconds();
$.get(sURL, null, function(data, status) {
// your work
});
IE es notorio por su almacenamiento en caché agresivo de las respuestas de Ajax. Como está utilizando jQuery, puede establecer una opción global:
$.ajaxSetup({
cache: false
});
lo que hará que jQuery agregue un valor aleatorio a la cadena de consulta de solicitud, impidiendo así que el IE guarde en caché la respuesta.
Tenga en cuenta que si tiene otras llamadas Ajax en curso en las que desea el almacenamiento en caché, esto también lo desactivará. En ese caso, cambie a usar el método $ .ajax () y habilite esa opción explícitamente para las solicitudes necesarias.
Consulte http://docs.jquery.com/Ajax/jQuery.ajaxSetup para obtener más información.
IE está dentro de sus derechos para hacer este almacenamiento en caché; para asegurarse de que el elemento no se almacena en caché, los encabezados deben establecerse en consecuencia.
Si está utilizando ASP.NET MVC, puede escribir un ActionFilter
; en OnResultExecuted
, marque filterContext.HttpContext.Request.IsAjaxRequest()
. De ser así, establezca el encabezado de expiración de la respuesta: filterContext.HttpContext.Response.Expires = -1;
Según http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ :
Algunas personas prefieren usar el encabezado Cache - Control: no - cache en lugar de caducar. Aquí está la diferencia:
Cache-Control: no-cache - absolutamente NO almacenamiento en caché
Caduca: -1 - el navegador "normalmente" se pone en contacto con el servidor web para las actualizaciones de esa página a través de una solicitud condicional If-Modified-Since. Sin embargo, la página permanece en la memoria caché de disco y se utiliza en situaciones apropiadas sin contactar al servidor web remoto, como cuando se utilizan los botones ATRÁS y AVANZAR para acceder al historial de navegación o cuando el navegador está en modo fuera de línea.
Las respuestas aquí son muy útiles para aquellos que usan jQuery o, por alguna razón, usan directamente el objeto xmlHttpRequest ...
Si está utilizando el proxy de servicio de Microsoft generado automáticamente, no es tan simple de resolver.
El truco es usar el método Sys.Net.WebRequestManager.add_invokingRequest en el controlador de eventos para cambiar la URL de solicitud:
networkRequestEventArgs._webRequest._url = networkRequestEventArgs._webRequest._url + ''&nocache='' + new Date().getMilliseconds();
He blogueado sobre esto: http://yoavniran.wordpress.com/2010/04/27/ie-caching-ajax-results-how-to-fix/
NickFitz da una buena respuesta, pero también tendrás que desactivar el almacenamiento en caché en IE9. Para apuntar solo a IE8 e IE9 puedes hacer esto;
<!--[if lte IE 9]>
<script>
$.ajaxSetup({
cache: false
});
</script>
<![endif]-->
Obtiene siempre se puede almacenar en la memoria caché. Una estrategia que puede funcionar es editar el encabezado de respuesta y decirle al cliente que no guarde en caché la información o caduque el caché muy pronto.
Si está utilizando Asp.net MVC, es suficiente agregar esta línea en la parte superior de la acción del controlador
[OutputCache(NoStore=true, Duration = 0, VaryByParam = "None")]
public ActionResult getSomething()
{
}
Si llama a la página de ashx, también puede desactivar el almacenamiento en caché en el servidor con el siguiente código:
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
esto es lo que hago para las llamadas ajax:
var url = "/mypage.aspx";
// my other vars i want to add go here
url = url + "&sid=" + Math.random();
// make ajax call
Funciona bastante bien para mí.