2008-11-05 13 views
101

Estoy jugando con ASP.net MVC y JQuery en este momento. Me he encontrado con un comportamiento que no parece tener sentido.

Llamo a la función $.getJSON de JQuery para completar algunos div. El evento se desencadena en el evento $(document).ready. Esto funciona perfectamente

Hay un pequeño AJAX.BeginForm que agrega otro valor que se utilizará al rellenar los divs. Llama a la función remota correctamente y luego de un éxito llama a la función javascript original para volver a llenar los divs.

Aquí está la parte extraña: en FireFox y Chrome: todo funciona. PERO en IE8 (Beta), esta segunda llamada a la secuencia de comandos Div (que llama a la función $ .getJSON) obtiene datos en caché y no se lo pide al servidor.

Espero que esta pregunta tenga sentido: En una cáscara de nuez - ¿Por qué se obtiene $.getJSON datos en caché? ¿Y por qué solo está afectando a IE8?

+0

Extrañamente, veo este error no solo en IE, sino también en Firefox. Desactivar el almacenamiento en caché ajax en jquery me ayudó. –

Respuesta

66

Solo para hacerte saber, Firefox y Chrome consideran que todas las solicitudes de Ajax no son almacenables. IE (todas las versiones) trata la llamada Ajax como otra solicitud web. Es por eso que ves este comportamiento.
Cómo forzar IE para descargar datos a cada solicitud:

  • Como usted ha dicho, el uso 'caché' o la opción 'nocache' en jQuery
  • Añadir un parámetro aleatorio a la petición (feo, pero funciona:))
  • en el lado del servidor, establecer cachability (por ejemplo, usando un atributo, ver más abajo)

Código:

public class NoCacheAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext context) 
    { 
     context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    } 
} 
+1

Esta solución me atrae. Me gusta mucho la elegancia de aplicar un attibute en MVC –

+1

Hay un OutputCacheAttribute OOTB hoy en día. – bzlm

+1

@bzlm, pero esto es más fácil de buscar –

2

Es posible que deba enviar un interruptor de memoria caché.

Yo recomendaría el uso de $ .ajax ({cache: no}) por si acaso (añade un sufijo al azar a la solicitud GET)

(que tienden a utilizar $ .ajax en todas partes estos días, más sintonizable)

+0

¡Gracias por su respuesta! ... aún no lo he probado. Proporcionará retroalimentación en breve –

16

Gracias Kent por su respuesta. Usando $ .ajax ('{caché: no}'); funcionó perfectamente [editar]

O al menos yo pensé que sí. Parece que jquery $ .getJSON no lee ningún cambio realizado en el objeto $ .ajax.

La solución que terminó trabajando era añadir un nuevo parámetro manualmente

var noCache = Date(); 
$.getJSON("/somepage/someaction", { "noCache": noCache }, Callback); 

la resolución de fecha es sólo a la hora; lo que significa que esta solución todavía almacena en caché hasta por un minuto. Esto es aceptable para mis propósitos.

+9

var noCache = new Date(). GetTime(); // te daré el ms – scunliffe

+0

gracias Scunliffe! - Soy bastante nuevo en javascript, ASP MVC me ha abierto nuevos horizontes –

+0

También puedes probar algo como Math.Random(). – Falkayn

105

Ésta es la forma en que trabajó para mí ...

$.ajaxSetup({ cache: false }); 
$.getJSON("/MyQueryUrl",function(data,item) { 
    // do stuff with callback data 
    $.ajaxSetup({ cache: true }); 
    }); 
+0

Estaba luchando con este problema y su solución dio una forma rápida de resolverlo. :) Tengo una pregunta, ¿sabes qué opciones se pueden usar para $ .ajaxSetup? La documentación de jQuery no proporciona detalles, lamentablemente ... – Achimnol

+1

Las opciones disponibles son idénticas a $ .ajax Consulte http://docs.jquery.com/Ajax/jQuery.ajax#options para obtener más información –

+12

Una pequeña advertencia para el código anterior - contiene condiciones de carrera. Debido a que la llamada y su respuesta son asíncronas, debe llamar '$ .ajaxSetup ({cache: true});' justo después de 'getJSON()' y no en la devolución de llamada. – sax

4

Si está utilizando ASP.MVC red, considerar la adición de un método de extensión para implementar fácilmente sin almacenamiento en caché de este modo:

public static void NoCache(this HttpResponse Response) 
    { 
     Response.Cache.SetNoStore(); 
     Response.Cache.SetExpires(DateTime.MinValue); 
     Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     Response.Cache.SetValidUntilExpires(false); 

     Response.Expires = -1; 
     Response.ExpiresAbsolute = DateTime.MinValue; 
     Response.AddHeader("Cache-Control", "no-cache"); 
     Response.AddHeader("Pragma", "no-cache"); 
    } 
+0

Buena idea, por lo que llama a este método de extensión en el servidor durante la devolución de llamada ¿no? – Guy

11

He resuelto este mismo problema colocando el atributo siguiente en la acción en el controlador:

[OutputCache(Duration = 0, VaryByParam = "None")] 
+0

¡Maravilloso! Es bueno tener alternativas (yo elegí esta). ¡Gracias a todos los colaboradores! –

+0

Funcionó para mí, gracias. Me encanta IE – Matt

+0

Funciona bien con Asp.Net MVC 4.0 – Mayank

Cuestiones relacionadas