Posso usar window.location.replace em um iframe?


15

Podemos usar window.location.replacepara evitar o histórico e direcionar âncoras na página sem recarregamentos, mas não em iframes?

O problema é uma violação do CSP (política de segurança de conteúdo), cujos estados script-src 'unsafe-inline'devem estar ativados. Exceto que eu não tenho um CSP definido, e mesmo se eu definir um e permitir que script-src 'unsafe-inline'ele ainda dê o mesmo erro de violação. Mesmo resultado em ie11 / chrome / ff.

Iframe no mesmo domínio (no mesmo diretório).

  1. Alveje o iframe no console e use window.location.replace('/samepage.html#onpage_anchor')no console.
  2. funciona. Ele tem como alvo a âncora da página sem recarregar a página e sem histórico.
  3. Coloque o mesmo código embutido nos links âncora e ele funciona.
  4. Use o mesmo código no script externo, obtenha o erro de violação da csp. Isso funciona bem se não estiver em um iframe.

Tentei criar um CSP para permitir a ação, mas nem mesmo as políticas de segurança de conteúdo mais permissivas possíveis o permitiriam.


Edit: então eu montei exemplos no plunker que permite vários arquivos para que eu pudesse usar hrefs adequados que fazem referência às páginas pai / filho.

Notas sobre os exemplos de plunker:

  1. O problema não é reproduzido nesses exemplos. O script funciona perfeitamente, mesmo no iframe. No entanto, o mesmo código não funciona no meu servidor local ou quando eu o executo ao vivo em um VPS.

  2. Suspeito que a violação do CSP não seja acionada no plunker, porque ele apresenta o conteúdo ao navegador por meio de uma espécie de camada de abstração de algum tipo.

  3. A primeira vez que você clica nos links de acordeão no pai, isso causa uma atualização. Isso ocorre porque o modo como a página é carregada inicialmente não faz referência a index.html. Os cliques subsequentes funcionam conforme o esperado, sem recarregamentos de página. Não é um problema no iframe porque faz referência inicialmente a child.html

  4. Estes são bons exemplos para mostrar o código sem exigir alterações para fazê-lo funcionar (como na necessidade de alterar os hrefs para fazê-los funcionar nos snippets de fluxo de pilha, mencionados abaixo). Também é bom, pois mostra o javascript funcionando como deveria. Mas isso não mostra o problema realmente. Você ainda precisará carregá-lo em seu editor e executá-lo em um servidor local ou em um ambiente de hospedagem ao vivo para ver o problema real.

Exemplos de Plunker

Com roteiro: Sem histórico
Sem roteiro: Com histórico


Exemplo de código simplificado

Acordeão simples com uma entrada. Suficiente para reproduzir o problema.

Clicar em abrir / fechar expandirá / reduzirá o acordeão, sem a necessidade de JS. O JS deve fazer exatamente a mesma coisa, mas sem histórico. Funciona bem, mas não em um iframe.

Notas do fragmento de código:

  1. Você pode executar o trecho para ter uma idéia do que estou descrevendo, mas na verdade não demonstra o problema.

  2. O snippet não se comporta da mesma maneira que em um navegador real, o javascript não funciona.

  3. O trecho mostra o código, mas deve ser executado em um iframe para ver o problema. Execute-o fora de um iframe para ver a diferença e como deve funcionar.

  1. Por causa de como os links funcionam com o JS (substituindo o URL inteiro), eles devem ser assim, href="https://stackoverflow.com/thispage.html#ac1"e não href="#ac1"como aparecem no snippet (não é possível segmentar a página html real no snippet). Portanto, se você tentar fazer isso no seu editor (por favor, faça), lembre-se de alterar os links para este formato this_document.html#anchor para que eles ainda sejam as mesmas âncoras de página, mas o page.html está incluído no link.


O script

$(document).ready(function() {

      // anchor links without history
      $.acAnch = function(event) {
        event.preventDefault();
        var anchLnk = $(event.target);
        var anchTrgt = anchLnk.attr('href');
        window.location.replace(anchTrgt);
      }
      // listen for anchor clicks
      $('.accordion').on('click', 'a', $.acAnch);

    });

Isso é muito simples:
1. A função acAnch pega o hrefatributo e o insere window.location.replace().
2. Ouça os cliques nas âncoras no acordeão para executar a função acAnch.

Então, todo o script faz é executado window.location.replace('/this_same_page.html#on_page_anchor')

Se você colocar isso no console, ele funcionará, sem violação do CSP. Mas executá-lo a partir de script externo não funciona.

Inline nos links funciona bem:

onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"

Colocar isso nos respectivos links funciona perfeitamente , mas eu realmente prefiro não usar scripts embutidos como esse. Deve haver uma maneira de fazer isso com um script externo.

Tentei executar o javascript no pai, em vez de no iframe (com modificações para selecionar os links dentro do filho, é claro). O mesmo resultado de erro do CSP.


Por que estou fazendo isto?

Bem, o site é muito mais complexo que o exemplo. Âncoras em iframes funcionam bem, mas adicionam histórico. Se você executar o código acima sem o javascript (ou apenas executar o trecho), abra e feche o acordeão algumas vezes e use o botão Voltar, ele voltará aos estados de fechamento aberto.

Eu não me importaria com o histórico, mas se ele estiver em um iframe, quando você sair da página pai e voltar a ela, o histórico no iframe será quebrado. Voltar não volta mais aos estados de acordeão, mas continua recarregando o iframe. Inicialmente, as âncoras não causam recarregamentos de iframe, mas apenas passam pelo histórico de estado de acordeão, o que funciona bem, até você sair da página e voltar. O back não passa mais pelos estados de acordeão, mas apenas por uma pilha de iframe idênticos recarregados. É um comportamento muito hostil ao usuário.

Não preciso usar location.replace se houver outro método que funcione. No entanto, tentei muitas outras abordagens e descobri que os métodos que podem atingir o mesmo resultado geralmente resultam no mesmo erro.

O objetivo é simplesmente ativar os links de âncora na página sem recarregar e sem histórico dentro de um iframe.

O script embutido funciona. Podemos fazê-lo funcionar em um arquivo .js externo?


você está tentando alcançar a âncora? se assim for, <a href="#ac0" class="ac-close">Close</a>deve funcionar.
— Dementic

Ok, eu configuro exemplos no plunker. Infelizmente, o problema não é reproduzido no plunker. Em vez disso, o script funciona bem, mesmo em um iframe. com script - sem histórico e sem script tem histórico . Emissão menor de plunker; os links de acordeão no pai causam uma atualização da página, apenas o clicam pela primeira vez (carrega inicialmente sem a referência index.html, portanto, após o primeiro clique, ele funciona conforme o esperado, sem recarregamentos de página). Não é um problema para o iframe, pois ele é carregado com o child.html src.
— Veneseme Tyras 25/11/19

Portanto, pelo menos com os exemplos de plunker, você pode ver o código completo e como ele deve funcionar. Porém, ele não funciona no meu servidor local ou quando eu o executo ao vivo em um VPS. Vou atualizar a pergunta com os links e informações do afunilador.
— Veneseme Tyras 25/11/19

11
Levei o seu código de amostra para o meu servidor, ele está funcionando bem, então criei um novo exemplo de plunker a partir do seu exemplo plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p=preview , também está funcionando bem. Nenhum resultado de erro do CSP.
— Pensador

Sim, bem, funciona bem no desentupidor que eu também fiz. No entanto, estou curioso para saber como ele funciona no seu servidor, porque, após o seu comentário, verifiquei três vezes e não consigo fazê-lo funcionar no meu servidor ativo ou no meu servidor local.
— Veneseme Tyras

Respostas:



0

você pode usar CSS em vez da tag iframe html porque a tag iframe é removida em html


Dê uma olhada novamente em Como responder . Como exatamente eles resolveriam esse problema usando CSS?
— camille
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.