Evitar el almacenamiento en caché de iframe en el navegador

86

¿Cómo se evita que Firefox y Safari almacenen en caché el contenido del iframe?

Tengo una página web simple con un iframe a una página en un sitio diferente. Tanto la página externa como la interna tienen encabezados de respuesta HTTP para evitar el almacenamiento en caché. Cuando hago clic en el botón "Atrás" del navegador, la página exterior funciona correctamente, pero pase lo que pase, el navegador siempre recupera un caché de la página con iframed. IE funciona bien, pero Firefox y Safari me están dando problemas.

Mi página web se parece a esto:

<html>
  <head><!-- stuff --></head>
<body>
  <!-- stuff -->
  <iframe src="webpage2.html?var=xxx" />
  <!-- stuff -->
</body>
</html>

La varvariable siempre cambia. A pesar de que la URL del iframe ha cambiado (y, por lo tanto, el navegador debería realizar una nueva solicitud a esa página), el navegador simplemente obtiene el contenido almacenado en caché.

He examinado las solicitudes y respuestas HTTP que van y vienen, y me di cuenta de que incluso si la página exterior contiene <iframe src="webpage2.html?var=222" />, el navegador seguirá buscando webpage2.html?var=111.

Esto es lo que he probado hasta ahora:

  • Cambiar la URL del iframe con un valor var aleatorio
  • Adición de encabezados Expires, Cache-Control y Pragma a la página web externa
  • Agregar encabezados Expires, Cache-Control y Pragma a la página web interna

No puedo hacer ningún truco de JavaScript porque estoy bloqueado por la política del mismo origen.

Me estoy quedando sin ideas. ¿Alguien sabe cómo evitar que el navegador almacene en caché el contenido iframed?

Actualizar

Instalé Fiddler2 como sugirió Daniel para realizar otra prueba y, desafortunadamente, todavía obtengo los mismos resultados.

Esta es la prueba que realicé:

  1. La página externa genera un número aleatorio usando Math.random()JSP.
  2. La página exterior muestra un número aleatorio en la página web.
  3. La página externa llama a iframe, pasando un número aleatorio.
  4. La página interior muestra un número aleatorio.

Con esta prueba, puedo ver exactamente qué páginas se actualizan y qué páginas se almacenan en caché.

Prueba visual

Para una prueba rápida, cargo la página, navego a otra página y luego presiono "atrás". Aquí están los resultados:

Página original:

  • Página exterior: 0.21300034290246206
  • Página interna: 0.21300034290246206

Salir de la página y luego devolver el golpe:

  • Página exterior: 0.4470929019483644
  • Página interior: 0.21300034290246206

Esto muestra que la página interna se está almacenando en caché, aunque la página externa la está llamando con un parámetro GET diferente en la URL. Por alguna razón, el navegador ignora el hecho de que el iframe solicita una nueva URL; simplemente carga el antiguo.

Prueba de violinista

Efectivamente, Fiddler confirma lo mismo.

(Carga la página.)

Se llama la página externa. HTML:

0.21300034290246206
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.21300034290246206" />

Se llama http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 .

(Me alejo de la página y luego devuelvo el golpe).

Se llama la página externa. HTML:

0.4470929019483644
<iframe src="http://ipv4.fiddler:1416/page1.aspx?var=0.4470929019483644" />

Se llama http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 .

Bueno, a partir de esta prueba, parece que el navegador web no almacena en caché la página, sino que almacena en caché la URL del iframe y luego realiza una nueva solicitud en esa URL almacenada en caché. Sin embargo, todavía estoy perplejo en cuanto a cómo resolver este problema.

¿Alguien tiene alguna idea sobre cómo evitar que el navegador web almacene en caché las URL de iframe?

JR.
fuente
11
+1 - Tu escritura captura el dolor tan bien.
nickf
1
Gracias por la explicación muy detallada del problema, esto es 100% exactamente lo que estoy experimentando con un sitio. Han pasado siete años y el informe de errores de Firefox todavía está presente.
Scuzzy

Respuestas:

-3

Haga que la URL del iframe apunte a una página de su sitio que actúa como un proxy para recuperar y devolver el contenido real del iframe. Ahora ya no está sujeto a la política del mismo origen (EDITAR: no evita el problema de almacenamiento en caché de iframe).

kmoser
fuente
41
esto no evita la caché.
baash05
@ baash05 Nunca dije que lo hiciera; Dije que evita la política del mismo origen.
kmoser
1
Es cierto ... pero el título de la operación dice "Evitar el almacenamiento en caché de iframe en el navegador" y si su respuesta no evita el almacenamiento en caché de iframe en el navegador, no es realmente una respuesta. Es bueno saberlo, pero aún no es un buen consejo para alguien que busca evitar el almacenamiento en caché.
baash05
OP buscaba resolver el almacenamiento en caché y evitar la política del mismo origen. Una respuesta parcial es mejor que ninguna :)
kmoser
2
la tostada siempre cae con la mermelada hacia abajo :)
baash05
58

Este es un error en Firefox:

https://bugzilla.mozilla.org/show_bug.cgi?id=356558

Pruebe esta solución alternativa:

<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
Caleb
fuente
3
Hoy 27.2.2014 Estoy tan feliz de haber encontrado este hilo, pensé que podría resolverse sin almacenamiento en caché del lado del servidor. FF 27 todavía tiene este error.
Robert
7
7.8.2014 - 8 años después, y todavía no arreglado.
Łukasz Zaroda
Esto también se aplica al atributo srcdoc, tan extraño ... Tan agradecido que encontré esto.
elundmark
2
Encontré este mismo problema de almacenamiento en caché con Chrome y las dos líneas de JavaScript lo resolvieron. ¡Gracias!
Thorn
2
Vaya, tenía exactamente el mismo problema. Era específico para Firefox, funcionó bien en IE, Chrome, etc. Gracias @caleb. No puedo creer que esto haya durado tanto.
Voodoo
32

He podido solucionar este error estableciendo un nameatributo único en el iframe; por alguna razón, esto parece romper el caché. Puede usar cualquier dato dinámico que tenga como nameatributo, o simplemente el tiempo actual ms o ns en cualquier lenguaje de plantillas que esté usando. Esta es una solución mejor que las anteriores porque no requiere JS directamente.

En mi caso particular, el iframe se está construyendo a través de JS (pero podría hacer lo mismo a través de PHP, Ruby, lo que sea), así que simplemente uso Date.now():

return '<iframe src="' + src + '" name="' + Date.now() + '" />';

Esto corrige el error en mis pruebas; probablemente porque window.nameen la ventana interior cambia.

STRML
fuente
2
Esta respuesta funciona para Chrome, Firefox y Safari a finales de 2015.
rovermicrover
13

Como dijiste, el problema aquí no es el almacenamiento en caché de contenido de iframe , sino el almacenamiento en caché de URL de iframe .

A partir de septiembre de 2018, parece que el problema persiste en Chrome pero no en Firefox.

He intentado muchas cosas (agregar un parámetro GET cambiante, borrar la URL del iframe en onbeforeunload, detectar una "recarga desde el caché" usando una cookie, configurar varios encabezados de respuesta) y aquí están las únicas dos soluciones que funcionaron para mí:

1- Manera fácil: crea tu iframe dinámicamente desde javascript

Por ejemplo:

const iframe = document.createElement('iframe')
iframe.id = ...
...
iframe.src = myIFrameUrl 
document.body.appendChild(iframe)

2- Camino enrevesado

En el lado del servidor, como se explica aquí , deshabilite el almacenamiento en caché de contenido para el contenido que sirve para el iframe O para la página principal (cualquiera de las dos funcionará).

Y

Establezca la URL del iframe desde javascript con un parámetro de búsqueda cambiante adicional, como este:

const url = myIFrameUrl + '?timestamp=' + new Date().getTime()
document.getElementById('my-iframe-id').src = url

(versión simplificada, cuidado con otros parámetros de búsqueda)

steph643
fuente
5

Después de probar todo lo demás (excepto usar un proxy para el contenido del iframe), encontré una manera de evitar el almacenamiento en caché del contenido del iframe, desde el mismo dominio :

Utilice .htaccessuna regla de reescritura y cambie el srcatributo iframe .

RewriteRule test/([0-9]+)/([a-zA-Z0-9]+).html$ /test/index.php?idEntity=$1&token=$2 [QSA]

La forma en que uso esto es que la URL del iframe termina luciendo de esta manera: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

Donde [token] es un valor generado aleatoriamente. Esta URL evita el almacenamiento en caché de iframe ya que el token nunca es el mismo, y el iframe cree que es una página web totalmente diferente ya que una sola actualización carga una URL totalmente diferente:

example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html
example.com/test/54/d2cc21be7cdcb5a1f989272706de1913.html

ambos conducen a la misma página.

Puede acceder a sus parámetros de URL ocultos con $_SERVER["QUERY_STRING"]

Jeff Noel
fuente
1
Funcionó para mí - ¡Gracias!
Quinn Finney
@QuinnFinney Me alegra que esto haya sido útil para otra persona. Este problema me tomó unos días resolverlo :)
Jeff Noel
¡Sí yo también! jajaja
Quinn Finney
3

Para que el iframe cargue siempre contenido nuevo, agregue la marca de tiempo actual de Unix al final de los parámetros GET. El navegador entonces lo ve como una solicitud "diferente" y buscará contenido nuevo.

En Javascript, podría verse así:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
División seis
fuente
3

Encontré este problema en la última versión de Chrome, así como en la última versión de Safari en Mac OS X a partir del 17 de marzo de 2016. Ninguna de las correcciones anteriores funcionó para mí, incluida la asignación de src para vaciar y luego volver a algún sitio, o agregar algún parámetro de "nombre" con nombre aleatorio, o agregar un número aleatorio al final de la URL después del hash, o asignar la ventana de contenido href al src después de asignar el src.

En mi caso, fue porque estaba usando Javascript para actualizar el IFRAME y solo cambiaba el hash en la URL.

La solución en mi caso fue que creé una URL provisional que tenía un meta redireccionamiento de 0 segundos a esa otra página. Sucede tan rápido que apenas noto que la pantalla parpadea. Además, hice que el color de fondo de la página provisional fuera el mismo que el de la otra página, por lo que se nota aún menos.

Volomike
fuente
2

Configuré el atributo iframe src más adelante en mi aplicación. Para deshacerme del contenido en caché dentro del iframe al inicio de la aplicación, simplemente hago:

myIframe.src = "";

... en algún lugar al comienzo del código js (por ejemplo, en el controlador jquery $ ())

Gracias a http://www.freshsupercool.com/2008/07/10/firefox-caching-iframe-data/

janekw
fuente
0

También tuve este problema en 2016 con iOS Safari. Lo que pareció funcionar para mí fue darle un parámetro GET al iframe src y un valor como este

<iframe width="60%" src="../other/url?cachebust=1" allowfullscreen></iframe>

Lauri Kääriäinen
fuente
-1

¿Has instalado Fiddler2 ?

Le permitirá ver exactamente lo que se solicita, lo que se devuelve, etc. No parece plausible que el navegador realmente acceda a su caché para diferentes URL.

Daniel Earwicker
fuente
1
Gracias por el consejo sobre Fiddler2. Ahora sé que el navegador no almacena en caché el contenido del iframe; simplemente almacena en caché la URL del iframe. Sin embargo, todavía estoy perplejo y no tengo idea de por qué el navegador ignoraría la URL del iframe de la nueva página y simplemente usaría la URL anterior.
JR.
-1

Si desea volverse realmente loco, podría implementar el nombre de la página como una URL dinámica que siempre se resuelve en la misma página, en lugar de la opción de cadena de consulta.

Suponiendo que se encuentra en una oficina, verifique si hay algún almacenamiento en caché a nivel de red. Créame, es una posibilidad. Su personal de TI podrá decirle si hay alguna infraestructura de red en torno al almacenamiento en caché HTTP, aunque es poco probable que esto solo ocurre con el iframe.

Chris Webb
fuente
-2

¿Ha intentado agregar las diversas opciones de encabezado HTTP sin caché a la página iframe?

Chris Webb
fuente
Sip. Probé directivas sin caché tanto en los encabezados HTTP como en las metaetiquetas de cada página.
JR.