Prevenir o cache de iframe no navegador

86

Como você evita que o Firefox e o Safari armazenem conteúdo iframe em cache?

Tenho uma página da Web simples com um iframe para uma página em um site diferente. Tanto a página externa quanto a página interna têm cabeçalhos de resposta HTTP para evitar o armazenamento em cache. Quando clico no botão "voltar" no navegador, a página externa funciona corretamente, mas não importa o que aconteça, o navegador sempre recupera um cache da página iframed. O IE funciona bem, mas o Firefox e o Safari estão me causando problemas.

Minha página da web se parece com isto:

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

A varvariável sempre muda. Apesar de a URL do iframe ter mudado (e, portanto, o navegador deve estar fazendo uma nova solicitação para aquela página), o navegador apenas busca o conteúdo em cache.

Eu examinei as solicitações e respostas HTTP indo e voltando e percebi que mesmo se a página externa contiver <iframe src="webpage2.html?var=222" />, o navegador ainda fará a busca webpage2.html?var=111.

Aqui está o que tentei até agora:

  • Alterar URL iframe com valor var aleatório
  • Adicionar cabeçalhos Expires, Cache-Control e Pragma à página da web externa
  • Adicionar cabeçalhos Expires, Cache-Control e Pragma à página interna

Não consigo fazer nenhum truque de JavaScript porque estou bloqueado pela política de mesma origem.

Estou ficando sem ideias. Alguém sabe como impedir que o navegador armazene em cache o conteúdo iframed?

Atualizar

Instalei o Fiddler2 como Daniel sugeriu para realizar outro teste e, infelizmente, ainda estou obtendo os mesmos resultados.

Este é o teste que realizei:

  1. A página externa gera um número aleatório usando Math.random()em JSP.
  2. A página externa exibe um número aleatório na página da web.
  3. A página externa chama iframe, passando um número aleatório.
  4. A página interna exibe um número aleatório.

Com esse teste, posso ver exatamente quais páginas estão sendo atualizadas e quais estão armazenadas em cache.

Teste Visual

Para um teste rápido, eu carrego a página, navego para outra página e pressiono "voltar". Aqui estão os resultados:

Página original:

  • Página externa: 0,21300034290246206
  • Página interna: 0,21300034290246206

Saindo da página e voltando:

  • Página externa: 0,4470929019483644
  • Página interna: 0,21300034290246206

Isso mostra que a página interna está sendo armazenada em cache, embora a página externa a esteja chamando com um parâmetro GET diferente na URL. Por algum motivo, o navegador está ignorando o fato de que o iframe está solicitando um novo URL; ele simplesmente carrega o antigo.

Teste de Fiddler

Com certeza, Fiddler confirma a mesma coisa.

(Eu carrego a página.)

A página externa é chamada. HTML:

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

http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 é chamado.

(Eu saio da página e depois volto.)

A página externa é chamada. HTML:

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

http: //ipv4.fiddler: 1416 / page1.aspx? var = 0.21300034290246206 é chamado.

Bem, a partir desse teste, parece que o navegador da web não está armazenando em cache a página, mas está armazenando em cache a URL do iframe e, em seguida, fazendo uma nova solicitação nessa URL em cache. No entanto, ainda estou perplexo sobre como resolver esse problema.

Alguém tem alguma ideia sobre como impedir que o navegador da web armazene em cache os URLs do iframe?

JR.
fonte
11
1 - Sua escrita captura a dor tão bem.
nickf
1
Obrigado pela explicação muito detalhada do problema, isso é 100% exatamente o que estou experimentando com um site. Já se passaram sete anos e o relatório de bug do firefox ainda está presente.
Scuzzy

Respostas:

-3

Faça com que o URL do iframe aponte para uma página em seu site que atua como um proxy para recuperar e retornar o conteúdo real do iframe. Agora você não está mais sujeito à política de mesma origem (EDITAR: não evita o problema de cache do iframe).

kmoser
fonte
41
isso não impede o cache.
baash05
@ baash05 Nunca afirmei que sim; Eu disse que evita a política de mesma origem.
kmoser
1
Verdadeiro .. mas o título do op diz "Prevenindo o cache de iframe no navegador" e se sua resposta não impede o cache de iframe no navegador, não é realmente uma resposta. É legal saber, mas ainda não é um bom conselho para quem quer evitar o cache.
baash05 01 de
OP estava procurando resolver o cache e evitar a política de mesma origem. Uma resposta parcial é melhor do que nenhuma :)
kmoser
2
a torrada sempre cai com o lado da geléia para baixo :)
baash05
58

Este é um bug no Firefox:

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

Tente esta solução alternativa:

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

<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
Caleb
fonte
3
Hoje, 27.2.2014, estou tão feliz em encontrar este tópico, pensei que poderia ser resolvido pelo não cache do servidor O FF 27 ainda tem esse bug.
Robert
7
7.8.2014 - 8 anos depois e ainda não corrigido.
Łukasz Zaroda
Isso também se aplica ao atributo srcdoc, tão estranho ... Que bom que encontrei isso.
elundmark
2
Eu encontrei esse mesmo problema de cache com o Chrome e as duas linhas de JavaScript o resolveram. Obrigado!
Thorn
2
Uau, tive exatamente o mesmo problema. Era específico para Firefox - funcionou bem no IE, Chrome, etc. Obrigado @caleb. Não posso acreditar que isso durou tanto tempo.
Voodoo
32

Consegui contornar esse bug definindo um nameatributo exclusivo no iframe - por algum motivo, isso parece invadir o cache. Você pode usar quaisquer dados dinâmicos que tiver como nameatributo - ou simplesmente o tempo ms ou ns atual em qualquer linguagem de modelo que estiver usando. Esta é uma solução mais agradável do que as anteriores porque não requer JS diretamente.

No meu caso particular, o iframe está sendo construído via JS (mas você poderia fazer o mesmo via PHP, Ruby, qualquer que seja), então eu simplesmente uso Date.now():

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

Isso corrige o bug em meus testes; provavelmente porque o window.namena janela interna muda.

STRML
fonte
2
Esta resposta funciona para Chrome, Firefox e Safari no final de 2015.
rovermicrover 01 de
13

Como você disse, o problema aqui não é o cache de conteúdo iframe , mas o cache de url iframe .

Em setembro de 2018, parece que o problema ainda ocorre no Chrome, mas não no Firefox.

Eu tentei muitas coisas (adicionar um parâmetro GET variável, limpar o url do iframe em onbeforeunload, detectar um "recarregar do cache" usando um cookie, configurar vários cabeçalhos de resposta) e aqui estão as duas únicas soluções que funcionaram comigo:

1- Maneira fácil: crie seu iframe dinamicamente a partir de javascript

Por exemplo:

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

2- forma complicada

Do lado do servidor, conforme explicado aqui , desative o cache de conteúdo para o conteúdo que você serve para o iframe OU para a página pai (qualquer um ).

E

Defina o url do iframe em javascript com um parâmetro de pesquisa alterado adicional, como este:

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

(versão simplificada, cuidado com outros parâmetros de pesquisa)

steph643
fonte
5

Depois de tentar de tudo (exceto usar um proxy para o conteúdo do iframe), encontrei uma maneira de evitar o armazenamento em cache do conteúdo do iframe do mesmo domínio :

Use .htaccesse uma regra de reescrita e altere o srcatributo iframe .

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

A forma como eu uso isso é que o URL do iframe fica assim: example.com/test/54/e3116491e90e05700880bf8b269a8cc7.html

Onde [token] é um valor gerado aleatoriamente. Este URL impede o cache de iframe, pois o token nunca é o mesmo e o iframe pensa que é uma página da web totalmente diferente, pois uma única atualização carrega um URL totalmente diferente:

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

ambos levam à mesma página.

Você pode acessar seus parâmetros de url ocultos com $_SERVER["QUERY_STRING"]

Jeff Noel
fonte
1
Funcionou para mim - Obrigado!
Quinn Finney
@QuinnFinney Que bom que isso foi útil para outra pessoa. Este problema me levou alguns dias para resolver :)
Jeff Noel
Sim eu também! hahaha
Quinn Finney
3

Para fazer com que o iframe sempre carregue conteúdo novo, adicione o carimbo de data / hora Unix atual ao final dos parâmetros GET. O navegador então o vê como um pedido 'diferente' e buscará um novo conteúdo.

Em Javascript, pode ser semelhante a:

frames['my_iframe'].location.href='load_iframe_content.php?group_ID=' + group_ID + '&timestamp=' + timestamp;
Divisão Seis
fonte
3

Encontrei esse problema no Chrome mais recente, bem como no Safari mais recente no Mac OS X em 17 de março de 2016. Nenhuma das correções acima funcionou para mim, incluindo atribuir src para vazio e depois voltar para algum site ou adicionar algum parâmetro "nome" nomeado aleatoriamente, ou adicionar um número aleatório no final da URL após o hash, ou atribuir a janela de conteúdo href ao src após atribuir o src.

No meu caso, era porque estava usando Javascript para atualizar o IFRAME, e só trocando o hash na URL.

A solução alternativa no meu caso foi criar um URL provisório que tinha um meta redirecionamento de 0 segundos para essa outra página. Acontece tão rápido que quase não percebo o flash da tela. Além disso, fiz com que a cor de fundo da página intermediária fosse igual à da outra página, e você notará ainda menos.

Volomike
fonte
2

Eu defino o atributo iframe src posteriormente em meu aplicativo. Para me livrar do conteúdo armazenado em cache dentro do iframe no início do aplicativo, eu simplesmente faço:

myIframe.src = "";

... em algum lugar no início do código js (por exemplo, no manipulador jquery $ ())

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

Janekw
fonte
0

Eu também tive esse problema em 2016 com o iOS Safari. O que pareceu funcionar para mim foi dar um parâmetro GET ao iframe src e um valor para ele como este

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

Lauri Kääriäinen
fonte
-1

Você instalou o Fiddler2? ?

Ele permitirá que você veja exatamente o que está sendo solicitado, o que está sendo enviado de volta, etc. Não parece plausível que o navegador realmente acesse seu cache para URLs diferentes.

Daniel Earwicker
fonte
1
Obrigado pela dica sobre Fiddler2. Agora eu sei que o navegador não está armazenando em cache o conteúdo do iframe; é simplesmente armazenar em cache o URL do iframe. No entanto, ainda estou perplexo e não tenho ideia de por que o navegador iria ignorar o URL do iframe da nova página e simplesmente usar o URL antigo.
JR.
-1

Se você quiser realmente louco, pode implementar o nome da página como um url dinâmico que sempre resolve para a mesma página, em vez da opção querystring?

Supondo que você esteja em um escritório, verifique se há algum armazenamento em cache no nível da rede. Acredite em mim, é uma possibilidade. Seu pessoal de TI será capaz de dizer se há alguma infraestrutura de rede em torno do cache HTTP, embora, como isso só acontece para o iframe, seja improvável.

Chris Webb
fonte
-2

Você tentou adicionar as várias opções de cabeçalho HTTP para no-cache à página iframe?

Chris Webb
fonte
Sim. Tentei as diretivas sem cache nos cabeçalhos HTTP e nas metatags de cada página.
JR.