¿Qué significa agregar "? V = 1" a las URL de CSS y Javascript en etiquetas de enlace y script?

138

He estado mirando una plantilla HTML 5 repetitiva (de http://html5boilerplate.com/ ) y noté el uso de las "?v=1"URL al referirme a archivos CSS y Javascript.

  1. ¿Qué significa agregar "?v=1"a las URL de CSS y Javascript en etiquetas de enlace y script?
  2. No todas las URL de Javascript tienen el "?v=1"(ejemplo del ejemplo a continuación:) js/modernizr-1.5.min.js. ¿Hay alguna razón por la cual este es el caso?

Muestra de su index.html:

<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">

<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">

<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>

<!------ Some lines removed ------>

<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>

<!--[if lt IE 7 ]>
  <script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->


<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->
maxyfc
fuente

Respuestas:

175

Por lo general, son para asegurarse de que el navegador obtenga una nueva versión cuando el sitio se actualice con una nueva versión, por ejemplo, como parte de nuestro proceso de compilación, tendríamos algo como esto:

/Resources/Combined.css?v=x.x.x.buildnumber

Dado que esto cambia con cada nueva inserción de código, el cliente se ve obligado a tomar una nueva versión, solo por la cadena de consulta. Mire esta página (en el momento de esta respuesta) por ejemplo:

<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">

Creo que en lugar de un número de revisión, el equipo de SO eligió un hash de archivo, que es un enfoque aún mejor, incluso con una nueva versión, los navegadores solo se vieron obligados a tomar una nueva versión cuando el archivo realmente cambia.

Ambos enfoques le permiten configurar el encabezado de la caché en algo ridículamente largo, digamos 20 años ... sin embargo, cuando cambia, no tiene que preocuparse por ese encabezado de caché, el navegador ve una cadena de consulta diferente y la trata como un diferente, nuevo archivo.

Nick Craver
fuente
3
@Free: un encabezado de control de caché enviado ayer no puede decirle al cliente que el archivo cambió hoy (el cliente ni siquiera lo comprobará), una URL sí puede. ¿Puedes explicar lo que me falta allí?
Nick Craver
8
@Free - La forma en que estos archivos se almacenan en caché es para siempre , es decir, el cliente está en modo alguno la comprobación para ver si se modifica el archivo. Esto significa que nunca obtendrían el archivo actualizado ... a menos que la URL cambiara, que es lo que sucede con la técnica anterior. Obtiene la máxima duración de la memoria caché en el cliente (menos solicitudes HTTP) pero el cliente se actualiza instantáneamente cuando el archivo realmente cambia . Exactamente, ¿cómo lograrías todo esto usando solo encabezados de control de caché?
Nick Craver
44
@Free - Stack Overflow recibe 5 millones de visitantes al mes, su enfoque tendría 2 impactos: a) muchas más solicitudes y datos enviados a / desde nuestros servidores, yb) los usuarios no obtendrían inmediatamente JavaScript / CSS nuevo (por ejemplo cuando tuvimos un error, o el HTML cambia y necesita un nuevo JS / CSS). La expiración natural realmente no es una opción aquí. El método que está proponiendo sería técnicamente mucho menos eficiente y el resultado son errores reales del usuario , de forma regular ... eso no es realmente aceptable en ningún sitio importante (ni debería ser om en ningún sitio realmente).
Nick Craver
2
@Free: los 5 millones son 5 millones de visitantes por mes , ya que implementamos muchas veces al día , las solicitudes son muchas veces más. En términos de carga de páginas HTML, estamos hablando de poco más de 110 millones por mes (y creciendo ... de nuevo, eso es solo cargas de páginas HTML). Para a) sí, muchos más o más descansos, es una compensación de cualquier manera en el tiempo de caché frente a los clientes que tienen el contenido correcto. Además, su lógica para b) es defectuosa, el html no está en caché, por lo que el uso de JS en caché que ya no funciona significa que solo los usuarios en caché se ven afectados, no que sean inmunes.
Nick Craver
55
@GMsoF v simplemente representa "versión" para nosotros, es una elección completamente arbitraria. Cualquier cadena de consulta de valor funcionaría, por ejemplo, podría ser fácilmente? Jejdutogjesudo =
Nick Craver
23

Esto asegura que esté obteniendo la última versión del archivo css o js del servidor.

Y luego puede agregar "?v=2"si tiene una versión más nueva "?v=3", "?v=4"y así sucesivamente.

Tenga en cuenta que puede usar cualquier querystring, 'v' no es imprescindible, por ejemplo:

"?blah=1"funcionará también.

Y

"?xyz=1002" trabajará.

Y esta es una técnica común porque los navegadores ahora almacenan en caché archivos js y css mejor y durante más tiempo.

Amr Elgarhy
fuente
13

La solución hash es agradable, pero no es realmente legible para los humanos cuando quieres saber qué versión del archivo se encuentra en tu carpeta web local. La solución es date/timeestampar su versión para que pueda compararla fácilmente con su archivo de servidor.

Por ejemplo, si su .js or .cssarchivo está fechado 2011-02-08 15:55:30(última modificación), la versión debería ser igual a.js?v=20110208155530

Debe ser fácil de leer las propiedades de cualquier archivo en cualquier idioma. En ASP.Net es realmente fácil ...

".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");

Por favor, consiga que se refactorice en propiedades / funciones primero y listo. No más excusas.

Buena suerte, art.

Arte
fuente
2
¿Qué sucede si está creando su sitio web solo con html js y css? Entonces, ¿cómo podemos inyectar automáticamente el nombre de la versión a los recursos estáticos?
Nishanth Nair
@ Whizkid747 respuesta tardía, pero para los recién llegados, cualquier sistema de compilación / compilación del sitio que esté usando debe tener una forma de obtener la fecha en milisegundos que puede usar como versión, de lo contrario si no está usando un constructor // sistema de compilación tendrías que escribir esto tú mismo.
AntK
7

El navegador suele almacenar en caché los archivos Javascript durante mucho más tiempo de lo esperado.

Esto a menudo puede provocar un comportamiento inesperado cuando libera una nueva versión de su archivo JS.

Por lo tanto, es una práctica común agregar un parámetro QueryString a la URL del archivo javascript. De esa manera, el navegador almacena en caché el archivo Javascript con v = 1. Cuando lanza una nueva versión de su archivo javascript, cambia las URL a v = 2 y el navegador se verá obligado a descargar una nueva copia.

Día de robin
fuente
¿Qué navegadores exactamente? incluso los más extravagantes IE 5 y 6 obedecían los encabezados de control de caché.
Consultoría gratuita el
7

Para responder sus preguntas;

"? v = 1" esto se escribe solo porque se descarga una copia nueva de los archivos css y js en lugar de usarlos desde la caché del navegador.

Si menciona este parámetro de cadena de consulta al final de su hoja de estilo o el archivo js, ​​obliga al navegador a descargar un nuevo archivo, debido a lo cual los cambios recientes en los archivos .css y .js se hacen efectivos en su navegador.

Si no usa este control de versiones, es posible que deba borrar el caché para actualizar la página para ver los cambios recientes en esos archivos.

Aquí hay un artículo que explica esto Cómo y por qué hacer versiones de archivos CSS y JS

Tapan kumar
fuente
2

Durante el desarrollo / prueba de nuevas versiones, la memoria caché puede ser un problema porque el navegador, el servidor e incluso a veces la compañía telefónica 3G (si realiza una implementación móvil) almacenará en caché el contenido estático (por ejemplo, JS, CSS, HTML, img). Puede superar esto agregando un número de versión, un número aleatorio o una marca de tiempo a la URL, por ejemplo: JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

En caso de que esté ejecutando HTML puro (en lugar de páginas de servidor JSP, ASP, PHP), el servidor no lo ayudará. En el navegador, los enlaces se cargan antes de que se ejecute JS, por lo tanto, debe eliminar los enlaces y cargarlos con JS.

// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];   
for (i=0; i < cacheBust.length; i++){
     var el = document.createElement('script');
     el.src = cacheBust[i]+"?v=" + Math.random();
     document.getElementsByTagName('head')[0].appendChild(el);
}
Conete Cristian
fuente
0

Como puede leer antes, esto ?v=1garantiza que su navegador obtenga la versión 1 del archivo. Cuando tiene una nueva versión, solo tiene que agregar un número de versión diferente y el navegador se olvidará de la versión anterior y cargará la nueva.

Hay un complemento de Gulp que se encarga de la versión de sus archivos durante la fase de compilación, por lo que no tiene que hacerlo manualmente. Es práctico y puede integrarlo fácilmente en su proceso de construcción. Aquí está el enlace: gulp-annotate

Phugo
fuente
-2

Como lo mencionaron otros, esto se usa para el busting de caché front-end. Para implementar esto, personalmente he encontrado útil el paquete grunt-cache-bust npm.

RAM
fuente
1
Si bien este enlace puede responder a la pregunta, se desaconsejan las respuestas de solo enlace en Stack Overflow, puede mejorar esta respuesta tomando partes vitales del enlace y poniéndola en su respuesta, esto asegura que su respuesta siga siendo una respuesta si el enlace se cambia o eliminado :)
WhatsThePoint