2011-05-13 13 views
12

Es bien conocido que Internet Explorer aggressively caches ajax calls mientras que todos los demás navegadores toman los datos frescos cada vez. Esto generalmente es malo: nunca he encontrado un caso en el que quiera que ajax NO contacte al servidor. Firefox, Safari y los otros navegadores lo saben y no almacenan en caché las llamadas ajax.Grails: la mejor manera de enviar encabezados de caché con cada llamada de ajax

para prevenir EI de almacenamiento en caché, que tiene que hacer uno de los siguientes:

  • añadir una ficha cachebuster a la cadena de consulta (como ?time=[timestamp])
  • enviar una cabecera de respuesta HTTP que prohíbe específicamente IE para almacenar en caché la solicitud
  • utilizar un POST de Ajax en lugar de un GET

me gusta mucho más el establecimiento de un encabezado no-cache. Es la forma correcta: le dice a todos los navegadores que no guarden en la memoria caché, que es exactamente lo que pretendes. El método de cadena de consulta llena el caché del navegador con cosas que nunca se recuperarán, dejando menos espacio para el contenido legítimo del caché. Y el método POST es una corrupción de HTTP: los POST son para modificar datos.

En Grails, ¿cuál es la mejor manera de enviar automáticamente un encabezado do-not-cache para todas las solicitudes ajax? No quiero modificar ningún controlador, así que creo que tiene que haber un buen truco de filtro o algo así.

Gracias!

Respuesta

19

Esto es lo que finalmente descubrió. La mayoría de las bibliotecas de JavaScript, incluidos jQuery, YUI, Mootools y Prototype, envían el encabezado X-Requested-With: XmlHttpRequest en cada solicitud de AJAX.

Para cualquier solicitud que envíe este encabezado, puede enviar un encabezado de respuesta que indique que no tiene memoria caché.

A continuación se muestra un filtro Griales que impide el almacenamiento en caché de peticiones Ajax que se identifican con el encabezado: X-Requested-With: XmlHttpRequest

// put this class in grails-app/config/ 
class AjaxFilters { 
    def filters = { 
     all(controller:'*', action:'*') { 
      before = { 
       if (request.getHeader('X-Requested-With')?.equals('XMLHttpRequest')) { 
        response.setHeader('Expires', '-1') 
       } 
      } 
     } 
    } 
} 

Algunas personas prefieren utilizar el Cache-Control: no-cache encabezado en lugar de que expire. Aquí está la diferencia:

  • Cache-Control: no-cache - absolutamente ningún almacenamiento en caché
  • Expira: -1 - el navegador "por lo general" contacta con el servidor Web para la actualización de dicha página a través de un condicional If-Modified-Since request. 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.

Al agregar este filtro, hace que el almacenamiento en caché de Internet Explorer sea coherente con lo que ya hacen Firefox y Safari.

Por cierto, he experimentado el problema de almacenamiento en caché en IE8 e IE9.Supongo que el problema también existía para IE7 e IE6.

+0

El problema es definitivamente en IE7 también. Thx, nos ayudó. – Chris

+2

También puede usar if (request.xhr) para averiguar si su solicitud es a través de AJAX. –

2

Nosotros usamos jQuery para todas las llamadas AJAX así que agregamos este bloque a nuestra main.gsp (diseño de nivel superior):

<g:javascript> 
    jQuery(document).ready(function() { 
    $.ajaxSetup({ 
     cache:false 
    }); 
    }); 
</g:javascript> 

también respondió here

+0

¿Qué sucede si la página web que hace la llamada AJAX vive en otro sitio web? ejemplo: sirves una API ... – Grooveek

+0

Genial, gracias @ david-betts. Estamos usando YUI, pero acabo de buscar y tiene la misma funcionalidad. Usaré esto si tengo que ... pero preferiría controlar esto en el servidor porque agregar cosas a la URL puede tener efectos secundarios. Si nadie responde mañana al servidor, aceptaré este. –

+0

Si realiza la llamada ajax a cualquier sistema a través de jQuery después de realizar esta configuración, mi expectativa sería que no se almacenaría en caché, ya que agrega una marca de tiempo a cada solicitud. –

Cuestiones relacionadas