Por que os disjuntores de quadros funcionam em vários domínios e você pode usar disjuntores de quadros condicionalmente?

StackOverflow https://stackoverflow.com/questions/952242

Pergunta

Eu estive investigando quebra de quadro código recentemente e encontrei alguns comportamentos realmente bizarros relacionados ao política de mesmas origens que estou tendo dificuldade em entender.

Suponha que eu tenha uma página Breaker.html no domínio A e uma página Container.html no domínio B.O exemplo de código do disjuntor de quadro iria para Breaker.html, como abaixo:

if (top !== self) top.location.href = self.location.href;

Isso quebrará com sucesso o Breaker.html do Container.html, mas não entendo por que deveria.Da minha leitura da política das mesmas origens, top.location não deveria estar acessível de forma alguma, já que Container.html está em um domínio diferente de Breaker.html.Ainda mais estranho, parece que top.location somente gravação:

// Fails if Container.html is on a different domain than Breaker.html
alert(top.location);

Isso é problemático para mim porque estou tentando escrever um código que permita que minha página esteja em um iframe, mas apenas se estiver no mesmo domínio que seu pai (ou em um domínio permitido configurado).No entanto, parece ser impossível determinar isto, uma vez que a mesma política de origens me nega acesso à localização dos pais.

Então, eu tenho duas perguntas, basicamente:

  1. Por que o código do disjuntor de quadro acima funciona?

  2. Existe alguma maneira de quebrar frames condicionalmente ou a única verificação que se pode fazer é se top !== self?(Em particular, quero poder ler o domínio, para poder fornecer uma lista de domínios permitidos;simplesmente verificar se estou no mesmo domínio ou não não seria o ideal.)

Foi útil?

Solução

Para a sua resposta para o número 1: Em termos de segurança, há uma grande diferença entre o acesso de leitura e acesso de gravação. Ser capaz de ler top.location.href é um problema de segurança. Ser capaz de write para top.location.href não é.

Como para a resposta à sua pergunta, eu não sei javascript bem o suficiente para ter certeza, mas uma idéia seria assumine que se lesse top.location falhar (cheque de exceções), ele está em um domínio diferente.

Outras dicas

A resposta à pergunta 1 é que o operador de igualdade pode ser usado contra top.location.href por razões de legado. Breaker.html não pode ler top.location.href mas pode compará-lo com outro valor.

A resposta à pergunta 2, então não se torna, você deve usar o! == para parte porque você não será capaz de fazer uma substring em top.location.href de um breaker.html domínios.

Eu posso estar errado, mas essa é a minha compreensão do mundo iframe atual.

Isto é para a pergunta número 2:Se quiser usar o HREF de parent.location (não top.location), você pode fazer o seguinte:

if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer;

Basicamente o que esse código faz é:
[1] Verificando se o quadro pai é o superior porque você pode obter apenas o HREF do pai, mesmo que não seja o quadro superior.
[2] Verificando se o histórico do iframe estava em branco antes de carregar sua fonte, porque senão...document.referrer retornará o último HREF neste histórico de quadros.

Depois disso, você tem um novo problema:caso o valor de history.length seja maior que um, você pode usar uma lista de permissões de nomes de host para verificar se ele deve ser aberto ou não:

if ([location.hostname, 'stackoverflow.com'].indexOf(location.hostname)>=0) hasToBeOpened=true;

Observe que você tem outra opção:pode usar uma landing page para verificar se a “primeira” página tem que abrir ou não, use este código:

<head>
<script>
var parentHREF;
if ((window.top === window.parent) && (history.length==1)) parentHREF=document.referrer;
if (/*conditions mentiones above*/) document.write("<META http-equiv='refresh' content='0;URL=http://example.com/go-here.html'>");
</script>
</head>

Fazendo desta forma, a "primeira" página substituirá o primeiro valor do histórico (neste caso é o primeiro).Esse código pressupõe que "example.com" é o seu domínio.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top