Antecedentes
Estoy escribiendo y usando una herramienta de administración de contenido basada en CGI (Perl) muy simple para dos sitios web pro-bono. Proporciona al administrador del sitio web formularios HTML para eventos en los que rellenan los campos (fecha, lugar, título, descripción, enlaces, etc.) y los guardan. En ese formulario, permito que el administrador cargue una imagen relacionada con el evento. En la página HTML que muestra el formulario, también estoy mostrando una vista previa de la imagen cargada (etiqueta img HTML).
El problema
El problema ocurre cuando el administrador quiere cambiar la imagen. Simplemente tendría que presionar el botón "buscar", elegir una nueva imagen y presionar ok. Y esto funciona bien.
Una vez que se carga la imagen, mi CGI de back-end maneja la carga y vuelve a cargar el formulario correctamente.
El problema es que la imagen que se muestra no se actualiza. La imagen anterior todavía se muestra, aunque la base de datos contiene la imagen correcta. Lo he reducido al hecho de que la IMAGEN ESTÁ CACHADA en el navegador web. Si el administrador presiona el botón RELOAD en Firefox / Explorer / Safari, todo se actualiza bien y la nueva imagen simplemente aparece.
Mi solución: no funciona
Estoy tratando de controlar el caché escribiendo una instrucción HTTP Expires con una fecha muy lejana en el pasado.
Expires: Mon, 15 Sep 2003 1:00:00 GMT
Recuerde que estoy en el lado administrativo y realmente no me importa si las páginas tardan un poco más en cargarse porque siempre están vencidas.
Pero, esto tampoco funciona.
Notas
Al cargar una imagen, su nombre de archivo no se guarda en la base de datos. Se renombra como Image.jpg (para simplificar las cosas al usarlo). Al reemplazar la imagen existente por una nueva, el nombre tampoco cambia. Solo cambia el contenido del archivo de imagen.
El servidor web es proporcionado por el servicio de alojamiento / ISP. Utiliza Apache.
Pregunta
¿Hay alguna manera de obligar al navegador web a NO almacenar en caché cosas de esta página, ni siquiera imágenes?
Estoy haciendo malabarismos con la opción de "guardar el nombre de archivo" con la base de datos. De esta manera, si se cambia la imagen, el src de la etiqueta IMG también cambiará. Sin embargo, esto requiere muchos cambios en todo el sitio y prefiero no hacerlo si tengo una mejor solución. Además, esto todavía no funcionará si la nueva imagen cargada tiene el mismo nombre (digamos que la imagen se retocó un poco y se volvió a cargar).
fuente
Respuestas:
Armin Ronacher tiene la idea correcta. El problema es que las cadenas aleatorias pueden colisionar. Yo usaría:
Donde "1222259157.415" es la hora actual en el servidor.
Genere tiempo por Javascript con
performance.now()
o por Python contime.time()
fuente
Solución simple: adjunte una cadena de consulta aleatoria a la imagen:
Lo que dice el RFC de HTTP:
Pero eso no funciona tan bien :)
fuente
Utilizo la función de tiempo modificado de archivos de PHP , por ejemplo:
Si cambia la imagen, se utiliza la nueva imagen en lugar de la almacenada en caché, debido a que tiene una marca de tiempo modificada diferente.
fuente
Yo usaría:
donde "20130910043254" es la hora de modificación del archivo.
Creo que hay dos tipos de soluciones simples: 1) las que se me ocurren primero (soluciones directas, porque son fáciles de encontrar), 2) las que se terminan después de pensarlo (porque son fáciles de utilizar). Aparentemente, no siempre se beneficiará si elige pensar las cosas. Pero creo que la segunda opción está bastante subestimada. Solo piensa por qué
php
es tan popular;)fuente
images.php
). Este script debe regenerarse en cada confirmación y elimina la sobrecarga de determinar los tiempos de modificación de los archivos.use Class = "NO-CACHE"
html de muestra:
jQuery:
javascript:
Resultado: src = "images / img1.jpg" => src = "images / img1.jpg? A = 0.08749723793963926"
fuente
Puede escribir un script proxy para servir imágenes, aunque eso es un poco más de trabajo. Algo le gusta esto:
HTML:
Guión:
En realidad, los encabezados sin caché o el número aleatorio en la imagen src deberían ser suficientes, pero dado que queremos ser a prueba de balas ...
fuente
Soy un NUEVO codificador, pero esto es lo que se me ocurrió, para evitar que el navegador se almacene en caché y mantenga las vistas de mi cámara web:
No estoy seguro de qué funciona en qué navegador, pero funciona para algunos: IE: funciona cuando se actualiza la página web y cuando se vuelve a visitar el sitio web (sin una actualización). CROMO: funciona solo cuando se actualiza la página web (incluso después de una nueva visita). SAFARI y iPad: no funciona, tengo que borrar el historial y los datos web.
¿Alguna idea sobre SAFARI / iPad?
fuente
Cambie esto y habrá solucionado su problema. Utilizo marcas de tiempo, como con las soluciones propuestas anteriormente: Image- <timestamp> .jpg
Presumiblemente, cualquier problema que esté evitando al mantener el mismo nombre de archivo para la imagen se puede superar, pero no dice cuáles son.
fuente
Revisé todas las respuestas en la web y la mejor parecía ser: (en realidad no lo es)
primero.
Sin embargo, si agrega el parámetro cache = none (que es una palabra estática "none"), no afecta a nada, el navegador aún se carga desde la caché.
La solución a este problema fue:
donde básicamente agregas la marca de tiempo de Unix para hacer que el parámetro sea dinámico y sin caché, funcionó.
Sin embargo, mi problema era un poco diferente: estaba cargando sobre la marcha la imagen del gráfico php generada y controlando la página con los parámetros $ _GET. Quería que la imagen se leyera de la caché cuando el parámetro URL GET permanezca igual, y no se guarde en caché cuando cambien los parámetros GET.
Para resolver este problema, necesitaba hash $ _GET pero como es una matriz, aquí está la solución:
Editar :
Aunque la solución anterior funciona bien, a veces desea publicar la versión en caché HASTA que se cambie el archivo. (con la solución anterior, deshabilita el caché para esa imagen por completo) Entonces, para servir la imagen en caché desde el navegador HASTA que haya un cambio en el uso del archivo de imagen:
fuente
filemtime
solución es mejor también porquemd5
requiere mucha potencia de procesamiento.Su problema es que, a pesar del
Expires:
encabezado, su navegador está reutilizando su copia de la imagen en la memoria antes de que se actualizara, en lugar de verificar su caché.Tuve una situación muy similar al cargar imágenes de productos en el back-end de administración para un sitio similar a una tienda, y en mi caso decidí que la mejor opción era usar JavaScript para forzar una actualización de imagen, sin usar ninguna de las técnicas de modificación de URL de otras personas Ya he mencionado aquí. En cambio, puse la URL de la imagen en un IFRAME oculto,
location.reload(true)
invoqué en la ventana del IFRAME y luego reemplacé mi imagen en la página. Esto obliga a actualizar la imagen, no solo en la página en la que estoy, sino también en las páginas posteriores que visito, sin que el cliente o el servidor tengan que recordar ninguna cadena de consulta de URL o parámetros identificadores de fragmentos.Publiqué un código para hacer esto en mi respuesta aquí .
fuente
Agregar una marca de tiempo
<img src="picture.jpg?t=<?php echo time();?>">
siempre le dará a su archivo un número aleatorio al final y lo detendrá
fuente
Con la posibilidad de que los proxy transparentes se comporten mal entre usted y el cliente, la única forma de garantizar totalmente que las imágenes no se almacenarán en caché es dándoles una uri única, algo así como etiquetar una marca de tiempo como una cadena de consulta o como parte de camino.
Si esa marca de tiempo corresponde a la última hora de actualización de la imagen, puede almacenar en caché cuando lo necesite y servir la nueva imagen en el momento justo.
fuente
Supongo que la pregunta original se refiere a las imágenes almacenadas con información de texto. Por lo tanto, si tiene acceso a un contexto de texto al generar src = ... url, considere almacenar / usar CRC32 de bytes de imagen en lugar de una marca de tiempo o aleatoria sin sentido. Luego, si se muestra la página con muchas imágenes, solo se recargarán las imágenes actualizadas. Eventualmente, si el almacenamiento de CRC es imposible, se puede calcular y agregar a la url en tiempo de ejecución.
fuente
Desde mi punto de vista, deshabilitar el almacenamiento en caché de imágenes es una mala idea. En absoluto.
El problema raíz aquí es: cómo forzar al navegador a actualizar la imagen, cuando se ha actualizado en el lado del servidor.
Nuevamente, desde mi punto de vista personal, la mejor solución es desactivar el acceso directo a las imágenes. En su lugar, acceda a las imágenes a través del filtro del servidor / servlet / otras herramientas / servicios similares.
En mi caso, es un servicio de descanso, que devuelve una imagen y adjunta ETag en respuesta. El servicio mantiene el hash de todos los archivos, si el archivo se cambia, el hash se actualiza. Funciona perfectamente en todos los navegadores modernos. Sí, lleva tiempo implementarlo, pero vale la pena.
La única excepción son los favicons. Por algunas razones, no funciona. No pude forzar al navegador a actualizar su caché desde el lado del servidor. ETags, Cache Control, Expires, Pragma headers, nada ayudó.
En este caso, parece que agregar un parámetro aleatorio / versión a la url es la única solución.
fuente
Idealmente, debe agregar un botón / combinación de teclas / menú a cada página web con una opción para sincronizar el contenido.
Para hacerlo, debe realizar un seguimiento de los recursos que pueden necesitar sincronizarse, y usar xhr para sondear las imágenes con una cadena de consulta dinámica, o crear una imagen en tiempo de ejecución con src usando una cadena de consulta dinámica. Luego, use un mecanismo de transmisión para notificar a todos los componentes de las páginas web que están utilizando el recurso para actualizar para usar el recurso con una cadena de consulta dinámica añadida a su url.
Un ejemplo ingenuo se ve así:
Normalmente, la imagen se muestra y almacena en caché, pero si el usuario presionó el botón, se envía una solicitud xhr al recurso con una cadena de consulta de tiempo adjunta; dado que se puede suponer que el tiempo es diferente en cada pulsación, se asegurará de que el navegador omita la memoria caché, ya que no puede determinar si el recurso se genera dinámicamente en el lado del servidor en función de la consulta, o si es estático recurso que ignora la consulta.
El resultado es que puede evitar que todos sus usuarios lo bombardeen con solicitudes de recursos todo el tiempo, pero al mismo tiempo, permita un mecanismo para que los usuarios actualicen sus recursos si sospechan que no están sincronizados.
fuente
Hice un script PHP que agrega automáticamente las marcas de tiempo para todas las imágenes en la página HTML. Solo necesita incluir este script en sus páginas. ¡Disfrutar!
http://alv90.altervista.org/how-to-force-the-browser-not-to-cache-images/
fuente
Debe usar un nombre de archivo único. Me gusta esto
Pero esta técnica significa un alto uso del servidor y un desperdicio de ancho de banda. En su lugar, debe usar el número de versión o la fecha. Ejemplo:
Pero desea que nunca sirva la imagen de la memoria caché. Para esto, si la página no usa caché de página , es posible con PHP o el lado del servidor.
Sin embargo, todavía no es efectivo. Motivo: caché del navegador ... El último pero más efectivo método es Native JAVASCRIPT. Este código simple encuentra todas las imágenes con una clase "NO-CACHE" y hace que las imágenes sean casi únicas. Ponga esto entre las etiquetas de script.
USO
RESULTADO (s) como este
fuente