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.