2012-08-10 24 views
9

Estoy intentando clonar una imagen que se genera aleatoriamente. Aunque estoy usando la misma URL, se carga una imagen diferente. (probado en Chrome y Firefox)Forzar el almacenamiento en caché de imágenes con javascript

No puedo cambiar el servidor de imágenes, así que estoy buscando una solución javascript/jQuery pura.

¿Cómo fuerza al navegador a reutilizar la primera imagen?

Firefox: Firefox Demo

Chrome: Chrome Demo

Inténtelo usted mismo (tal vez usted tiene que recargar varias veces verla)

Código: http://jsfiddle.net/TRUbK/

$("<img/>").attr('src', img_src) 
$("<div/>").css('background', background) 
$("#source").clone() 

Demostración: http://jsfiddle.net/TRUbK/embedded/result/

+0

Aparte de los problemas al azar, si logras que esto funcione, igual vas a tener un problema tan pronto como comiences a trabajar con los datos de imagen, porque la [imagen provino de un dominio diferente] (http : //stackoverflow.com/questions/9972049/cross-origin-data-in-html5-canvas). El error se espera según la especificación: http://www.whatwg.org/specs/web-apps/current-work/multipage/the- canvas-element.html#security-with- canvas-elements –

Respuesta

6

No puede cambiar el servidor de imágenes si no es el suyo, pero puede escribir trivialmente algo en su propio servidor para manejarlo.

Escribir algo en su lenguaje de servidor de elección (PHP, ASP.NET, lo que sea) que:

  1. Golpea http://a.random-image.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes y lo descarga. Generas una clave en una de dos vías. O bien, obtenga un resumen de todo el asunto (MD5 debería estar bien, no es un uso relacionado con la seguridad, por lo que las preocupaciones de que sea demasiado débil en estos días no se aplican). O obtenga el tamaño de la imagen; esta última podría tener algunos duplicados, pero es más rápida de producir.
  2. Si la imagen no está almacenada, guárdela en una ubicación usando esa clave como parte de su nombre de archivo, y el tipo de contenido como otra parte (en caso de que haya una mezcla de JPEG y PNG)
  3. Responda con una respuesta XML o JSON con el URI para la próxima etapa.

En su código de cliente lateral, usted golpea ese URI a través de XmlHttpRequest para obtener el URI para usar con sus imágenes. Si desea una nueva aleatoria, vuelva a hacer clic en esa primera URI, si desea la misma imagen para dos o más lugares, use el mismo resultado.

Ese URI golpea algo así como http://yourserver/storedRandImage?id=XXX donde XXX es la clave (hash o tamaño como se decidió anteriormente). El controlador busca las copias almacenadas de las imágenes y envía el archivo por la secuencia de respuesta con el tipo de contenido correcto.

Todo esto es muy fácil técnicamente, pero el posible problema es legal, ya que está almacenando copias de las imágenes en otro servidor, puede que ya no esté dentro de los términos de su acuerdo con el servicio que envía el imágenes.

+0

Este enfoque es inteligente, sin embargo, no resuelve mi problema. La imagen en sí es proporcionada por un servicio de terceros e incluida por su biblioteca javascript y es de inicio de sesión (cookie) dependiente. (Usé al azar -image.net solo para demostración) – jantimon

+0

Como en el usuario de su aplicación, ¿está conectado en el suyo? No funcionará en ese, no :( –

+0

Como no habrá una solución de trabajo como tenía en mente recompensa la recompensa por la respuesta con la mayor cantidad de votos. ¡Gracias por tu esfuerzo! – jantimon

1

Los encabezados que se envían desde el script del generador de imágenes aleatorias incluyen una declaración Cache-Control: max-age=0 que, en esencia, le indica al navegador que no almacene en caché la imagen.

Necesita modificar la secuencia de comandos/servidor del generador de imágenes para enviar los encabezados de almacenamiento en caché adecuados si desea que el resultado se guarde en caché.

También debe asegurarse de que la URL permanezca igual (no miré ese aspecto ya que se pasaron toneladas de parámetros).

+0

No puedo para cambiar los encabezados de las imágenes ya que no soy el propietario del servidor de imágenes. La url es la misma. – jantimon

+0

@Ghommey Bueno, probablemente ya no tengas opciones. Eso es lo que le dice al navegador cómo debe almacenar en caché el elemento. –

+0

¿por qué funciona después del primer clon? – jantimon

0

Dile a dejar de obtener una imagen aleatoria, parece funcionar de la manera deseada cuando agrego esta tercera llamada reemplazar:

// Get the canvas element. 
var background = ($("#test").css('background-image')), 
img_src = background.replace(/^.+\('?"?/, '').replace(/'?"?\).*$/, '').replace(/&fromrandomrandomizer=yes/,'') 
+0

Gracias, pero la url dada es solo un ejemplo y quiero tener imágenes aleatorias, por lo que desafortunadamente este enfoque no me funciona. – jantimon

+0

Pero solo estoy eliminando la parte aleatoria de la imagen CUANDO se clona. Es parte de ese proceso no decir que no puedes usar imágenes aleatorias. Entonces, una vez que se genera la imagen original, no se obtendrá una imagen aleatoria durante la clonación. – Dameo

+0

La imagen clonada debería ser la misma que la imagen aleatoria anterior. – jantimon

0

intento:

var myImg = new Image(); 
myImg.src = img_src; 

y luego añadir "MyIMG" a donde desee:

$(document).append(myImg); 
+0

Gracias pero no funciona. Recargue la siguiente página varias veces: http://jsfiddle.net/9ykXq/embedded/result/ – jantimon

1

En primer lugar, puede "forzar" cualquier cosa en la web. Si necesita forzar cosas, entonces el desarrollo web es el medio equivocado para usted.

Lo que podría intentar, es utilizar un canvas element para copiar la imagen. Ver https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images para ejemplos.

+2

¡Por favor no me diga qué puedo y no puedo forzar! Uso fuerzas todo el tiempo en el desarrollo web. Si quieres, puedo enseñarte. –

+4

@ j-man86 No forzaste nada. Acabas de hacer algo que funcionaba en todos los escenarios que probaste (posiblemente ignorando deliberadamente aquellos en los que sabías que no funcionaría). Mencione una cosa que "forzó" y puedo nombrar un escenario donde no funcionará (y sí, esos escenarios pueden ser poco probables o incluso concebidos, pero eso no cambiará el hecho de que su "forzamiento" no funcionaría, y por lo tanto no es "forzar"). – RoToRa

+0

Gracias @RoToRa esto funciona para firefox pero no para chrome :( http://jsfiddle.net/VT8c5/ – jantimon

0

lo hice con las secuencias de comandos violinista y tiene la misma imagen cada vez

#test { 
background:url(http://a.random-image.net.nyud.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes); 
width: 150px; 
height: 150px; 

}

nota del .nyud.net después de que el nombre de dominio.

1

Puede intentar guardar la representación base64 de la imagen.

Cargue la imagen en un div/canvas oculto, luego conviértalo en base64. (No estoy seguro de si se puede ocultar un lienzo, ni si es posible combinar el img con la etiqueta html4) Ahora puede almacenar la imagen "codificada" en una cookie y usarla ilimitadas veces ...

1

parece que hay dos soluciones:

  1. Si vas con el método de la lona, ​​ver si se puede obtener la imagen a cargar en el propio lienzo para que pueda manipular los datos de imagen directamente en lugar de hacer una segunda solicitud de http para la imagen. Puede alimentar los datos de imagen directamente en un segundo lienzo.
  2. Si va a construir un proxy, puede hacer que el proxy elimine la directiva No-Cache para que las solicitudes posteriores de su navegador usen el caché (no hay garantías aquí, depende de la configuración del navegador/usuario).
Cuestiones relacionadas