2011-10-03 7 views
5

Lo que me gustaría hacer es añadir una cadena de consulta al final de la ruta javascript para que cada vez que mi aplicación se actualice a una nueva versión, se descargue el javascript. Sin embargo, mientras la cadena de consulta sea la misma, quiero que siga usando la versión en caché sin hacer una solicitud http para verificar si el script ha cambiado.¿Firefox almacena en caché javascript y lo utiliza sin una solicitud si hay una cadena de consulta en la ruta?

La forma en que estoy logrando esto en PHP es leer la etiqueta CVS. Cuando estoy construyendo el código HTML de salida, he leído la etiqueta CVS y el uso que adjuntar al final del camino Javascript para que se crea una etiqueta de secuencia de comandos que se parece a esto:

<script src="javascript/messages/shipments.js?TPRSAPPS-DEV2_090828145712237-BRANCH" type="text/javascript"></script> 

Mientras la aplicación no ha cambiado, la etiqueta permanecerá igual y, por lo tanto, la cadena de consulta también lo hará. El navegador debe almacenar en caché el JS y no hacer ninguna solicitud de red porque la fecha de vencimiento es muy futura. Cada vez que se actualiza la aplicación, esa cadena de consulta cambiará y el navegador debería descargarla.

Esto funciona muy bien en IE8. Mi problema es con Firefox. Firefox guarda en caché los archivos, pero la próxima vez que cargue la página Firebug muestra una respuesta 304, lo que indica que todavía hizo una solicitud de red para el archivo y luego descubrió que no había cambiado.

Así que mi pregunta es, ¿firefox ignora el encabezado expira y el caché de javascript cuando hay una cadena de consulta?

Relacionados: what does firefox decide not to cache? Aparentemente Rails hace algo similar. Pero esto no responde mi pregunta.

Aquí está la respuesta que estoy recibiendo de nuevo en este archivo:

https://appdev.prsx.net/~jhargett/PRSApps-Motorlog/javascript/menuReader.js?TPRSAPPS-DEV2_090828145712237-BRANCH-DIFFERENT 

HTTP/1.1 304 Not Modified 
Date: Mon, 03 Oct 2011 18:35:26 GMT 
Server: Apache/2.2.3 (Red Hat) 
Connection: close 
Etag: "179010-3f8-49a9a74334200" 
Vary: Accept-Encoding 

La ficha Caché en Firebug dice:

Last Modified Mon Oct 03 2011 13:35:26 GMT-0500 (Central Daylight Time) 
Last Fetched Mon Oct 03 2011 13:35:26 GMT-0500 (Central Daylight Time) 
Expires Fri Oct 28 2011 18:33:31 GMT-0500 (Central Daylight Time) 
Data Size 345 
Fetch Count 12 
Device disk 
+3

¿Qué sus cabeceras de respuesta HTTP parecen? Eso es lo importante aquí. – Pointy

+2

Hacer un 304 es normal. Firefox enviará una solicitud GET para cada recurso en la página al menos una vez, con un encabezado "if-modified-since". Depende del servidor responder con contenido nuevo (200) o un 304. No modificado. –

+0

Si el encabezado caduca es muy lejano, debería hacer una solicitud. –

Respuesta

6

La lógica Firefox utiliza para decidir si hacer un GET condicional dado una respuesta en caché es así:

  1. Si hay un correspondiente cabecera Vary, revalidar.
  2. Si se supone que esta solicitud se cargue forzosamente desde la memoria caché, no la vuelva a validar.
  3. Si esta solicitud tiene el indicador "siempre validar", vuelva a validar.
  4. Si esta solicitud tiene el distintivo "nunca validar", entonces revalide solo si se trata de una respuesta sin almacenamiento o respuesta SSL sin caché.
  5. Si el código de estado de la respuesta no es almacenable en caché o la respuesta es no-cache o no-store o si el tiempo de caducidad es anterior a la fecha de la respuesta, revalide.
  6. Si hay un parámetro de consulta y la respuesta no tiene un expirado explícito o un máximo de edad, vuelva a validar.
  7. Si el tiempo de expiración de la respuesta es anterior, vuelva a validar (a menos que se establezca la preferencia de usuario "solo revalidar una vez por sesión").

Por lo tanto, para su caso, no debe haber un GET condicional, suponiendo que realmente establece la información de caducidad o de caducidad máxima en su respuesta 200.

Dicho esto, algunas de las herramientas que intentan rastrear la información HTTP para Firefox en realidad afectan el comportamiento de revalidación, por lo que es posible que se encuentre con eso.

Recomiendo crear un registro siguiendo los pasos en https://developer.mozilla.org/en/HTTP_Logging que de paso le dirán exactamente por qué se realiza un GET condicional, si puede encontrar la parte correcta del registro (busque "nsHttpChannel :: CheckCache enter" para el iniciar sesión desde la función que implementa la lógica anterior).

+0

Encontré mi respuesta basada en esta respuesta y en el comentario de Pointy anterior. Reexaminé mi encabezado de respuesta en la carga original no almacenada en caché (200). ¡No hubo un encabezado de expiración explícito! A pesar de que la pestaña Caché de Firefox mostraba una fecha de caducidad, no obtenía eso del encabezado HTTP. –

+1

@Jon el HTTP RFC define una heurística para determinar el tiempo de caducidad basado en la hora actual y el encabezado Fecha. Así que sí, te estabas viendo con el ítem 6 arriba, el cual está implementando http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9 párrafo 2. –

0

Lo que se está viendo es algo diferente a la realidad de descargar el archivo , y luego decir que no ha cambiado.

Firefox hace una solicitud HTTP para obtener la información del archivo, no el archivo en sí. Esto en realidad significa que Firefox está haciendo esto de manera más inteligente que IE.

La solicitud que hace firefox es solo un par de bytes grandes (tamaño de archivo, fecha, etc.). así que no importa el nombre, Firefox lo almacena en caché (a menos que esté desactivado). Si el archivo cambia, Firefox decide volver a descargar el archivo.

Lo que está señalando es en realidad el comportamiento correcto.

+0

Me doy cuenta de que no se está descargando todo el archivo, sino simplemente comprobando si está actualizado. Sin embargo, el objetivo de agregar futuro lejano expira ([yahoo] (http://developer.yahoo.com/performance/rules.html) es evitar incluso la solicitud de la red de verificar esto. De hecho, Firefox no hace la solicitud cuando no hay cadena de consulta. Se extrae de la memoria caché y Firebug muestra una línea atenuada con una respuesta de 200, lo que indica que utilizó el archivo de la memoria caché sin una solicitud. –

0

Si quiere estar absolutamente seguro de que su archivo se volverá a cargar, es mejor poner el número de versión/secuencia de caché directamente en el nombre del archivo. Entonces tendría algo como shipments_v2.js o shipments_(unix_timestamp).js. Esto se ocupará de los proxies y cualquier otro tipo de mecanismo de almacenamiento en caché.

+0

Correcto, pero eso requiere compilar scripts para cambie el nombre del archivo real. Supongo que también podría hacer algo en el archivo htaccess para quitar _v2.js y redirigirlo al archivo correcto. –

+0

Ambos son comentarios válidos.Si es un proyecto más grande, probablemente tendrá un script de compilación para minimizar los contenidos de todos modos, de lo contrario, si es solo un archivo, puede hacerlo a mano :) – deviousdodo

0

Como se explica en la respuesta de Boris, una de las condiciones que desencadena la solicitud condicional es la presencia del encabezado Vary. Por lo general, no quiere eliminar varían en Aceptar codificación, pero lo que puede hacer y lo que es bueno hacer en caso de que tenga versiones de URL es dejar el navegador sin nada para revalidar. En tu caso, es el encabezado de Etag. También puede ser el encabezado Last-Modified. Código de ejemplo para el barniz para hacer eso para usted puede tener este aspecto:

sub vcl_recv { 
    [..] 
     if (req.url ~ "\?v=\w+$") { 
      set req.http.X-Versioned = "1"; 
     } 
    [..] 
    } 

    sub vcl_deliver { 
    [..] 
     if (req.http.X-Versioned) { 
      unset resp.http.Etag; 
     } 
    [..] 
    } 
Cuestiones relacionadas