2012-07-04 13 views
6

Tengo una página a la que se puede acceder desde URL/productos. Cuando lo visito en un navegador, responde con una página completa dentro de un diseño. Aquí está un ejemplo simplificado de cabeceras de petición y respuesta del cuerpo:El navegador no distingue un HTML parcial obtenido a través de AJAX y una página completa

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

<layout> 
<products /> 
</layout> 

Cuando un usuario hace alguna búsqueda las actualizaciones de javascript resultados a través de AJAX. Los resultados se representan sin un diseño, ya que toma tiempo para hacer y yo no lo necesitan de todos modos:

Accept: */*;q=0.5, text/javascript, application/javascript, application/ecmascript, application/x-ecmascript 
X-Requested-With: XMLHttpRequest 

<products /> 

Por lo tanto, esto funcionó bien hasta que he añadido el almacenamiento en caché Cache-Control: private, max-age=3600. Inicialmente pensé que agregaría el encabezado Vary: X-Requested-With y un navegador distinguiría las dos respuestas. Sin embargo, cuando obtengo/productos a través de AJAX y luego visito/productos en el navegador, muestra la respuesta parcial de AJAX.

¿Hay una manera simple de resolver este problema?

P.S. Estoy usando Ruby on Rails y jQuery si eso importa.

+2

¿Has probado 'Vary: Accept'? – regilero

+0

Sí, no funciona también. Creo que el navegador está almacenando correctamente ambas respuestas en caché. Pero debido a Content-Type: text/html los trata por igual y muestra el último que resulta ser parcial. –

+0

En realidad, he tratado de responder con JSON, y ahora muestra JSON. Entonces esto no depende de Content-Type: text/html. Estoy bastante sorprendido de que "Variar" no tenga ningún efecto aquí. –

Respuesta

1

Haga que su llamada Ajax use una URL diferente como/products/partial.

+0

Parece la única solución por ahora. Pero significa que tendré que modificar cada URL en javascript del lado del cliente que no es muy conveniente. –

0

usted debe tener una url diferent para obtener resultados parciales (es decir,? = Parcial sí o algo así ...)

O

puede obtener toda la página a través de ajax y extraer sólo la parte que quiero usar jquery.load().

$("#productsContainerHolder").load("/my/products/url #productsContainer", { myParam: "beer", myParam2: "cold"}); 

$ .load llamará a su servidor con un método 'GET', recuperar todos los contenidos, extraer el #productsContainer de allí e insertar en "#productsContainerHolder"

<div id="productsContainerHolder"> 
    <div id="productsContainer> 
     ... 
    </div> 
</div> 
+0

No estoy procesando el diseño porque requiere una gran cantidad de tiempo de respuesta. La extracción no es realmente un problema aquí. –

0

Este article por Steve Luscher describe un caso similar, el problema fue más intermitente que lo que describes. Las soluciones propuestas son:

  1. cancelar todas las peticiones AJAX en el momento de enviar el formulario

  2. uso de una URL diferente de acuerdo a la respuesta que esperas

Steve fue por # 1 usando cancelar() en las solicitudes de ajax.

Usted no menciona lo que los navegadores que ha utilizado, no es una cuestión relacionada con el navegador here

+1

La primera solución no es realmente aplicable en mi situación. Pero estoy contento de ver a otras personas reportando el mismo problema. La pregunta que vinculó no parece estar relacionada para mí, pero estoy usando Safari. Probado en Firefox también. –

0

Uso Vary: Accept. Esto debería funcionar.

+0

Lo he intentado pero el problema sigue ahí. Copiando mis pensamientos desde arriba: creo que el navegador está guardando correctamente ambas respuestas en caché. Pero debido a Content-Type: text/html los trata por igual y muestra el último que resulta ser parcial. –

0

probablemente el más fácil es establecer en 'False' el parámetro 'caché' del método Ajax de jquery. Se agregará automáticamente una marca de tiempo al URI para evitar que se guarde en caché.

Esto se puede hacer uso de ancho con el siguiente fragmento:

$.ajaxSetup({ 
    cache: false 
}); 

Si la caché no importa incluso para la solicitud dinámica, puede generar la marca de tiempo a sí mismo en base a la fecha junto con la hora.

0

Intente enviar debe-revalidar en lugar de privado (que es más para proxy).

Cache-Control: max-age=3600, must-revalidate 

recomiendo la lectura de este artículo: http://www.mnot.net/cache_docs/ que podría ayudar. Y también use la herramienta http://redbot.org/ de Mark para probar sus resultados para eliminar su máquina local o isp o lo que no.

Cuestiones relacionadas