Acessar URL pai a partir de iframe

187

Ok, eu tenho uma página e nesta página eu tenho um iframe. O que preciso fazer é na página iframe, descobrir qual é o URL da página principal.

Eu pesquisei e sei que isso não é possível se minha página iframe estiver em um domínio diferente, pois isso é script entre sites. Mas em todo lugar que eu li diz que, se a página iframe estiver no mesmo domínio da página pai, ela funcionará se eu fizer, por exemplo:

parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href

... ou outros combos semelhantes, pois parece haver várias maneiras de obter a mesma informação.

Enfim, então aqui está o problema. Meu iframe está no mesmo domínio da página principal, mas não está no mesmo domínio SUB. Então, por exemplo, eu tenho

http: // www.mysite.com/pageA.html

e meu URL iframe é

http: // qa-www.mysite.com/pageB.html

Quando tento pegar o URL pageB.html(na página iframe), continuo recebendo o mesmo erro de acesso negado. Portanto, parece que até mesmo subdomínios contam como scripts entre sites, isso está correto ou estou fazendo algo errado?

chronofwar
fonte
Você pode simplesmente passá-lo no URL do quadro? Tais como<iframe src="url?parent=parent-url"></iframe>
Biagio Arobba

Respostas:

21

Você está certo. Os subdomínios ainda são considerados domínios separados ao usar iframes. É possível transmitir mensagens usando postMessage(...), mas outras APIs JS são intencionalmente inacessíveis.

Também é possível obter o URL, dependendo do contexto. Veja outras respostas para mais detalhes.

Dan Herbert
fonte
1
Ok, bem, isso apenas sopra. Mas pelo menos eu sei que não estou ficando louco :( Ah, bem, plano B. graças (e desculpe por não colocar minhas coisas em tags, obrigado pela edição).
chronofwar
9
como esta é a resposta selecionada? há descrições muito melhores de possíveis soluções abaixo.
Anoyz
1
Acordado! A resposta abaixo com 80 votos é muito melhor. Esta resposta está na especificação html.
Ligemer
4
Você pode interagir entre a 2. Mas você deve adicionar o seguinte script no pai e iframe: <script> document.domain = "mydomain.com"; </ script>
George
2
"Veja outras respostas para mais detalhes." hahah É como: não tenho solução, vejo outras respostas, mas aceite minha resposta também.
Milad
371

Sim, o acesso ao URL da página pai não será permitido se o iframe e a página principal não estiverem no mesmo (sub) domínio. No entanto, se você só precisa do URL da página principal (ou seja, o URL do navegador), pode tentar o seguinte:

var url = (window.location != window.parent.location)
            ? document.referrer
            : document.location.href;

Nota:

window.parent.locationé permitido; evita o erro de segurança no OP, causado pelo acesso à hrefpropriedade: window.parent.location.hrefcausas "Bloqueou um quadro com origem ..."

document.referrerrefere-se a "o URI da página vinculada a esta página". Isso pode não retornar o documento que contém se alguma outra fonte for o que determinou o iframelocal, por exemplo:

  • Contêiner iframe @ Domínio 1
  • Envia iframe filho para o Domínio 2
  • Mas no iframe filho ... O domínio 2 redireciona para o domínio 3 (por exemplo, para autenticação, talvez SAML) e o domínio 3 direciona de volta para o domínio 2 (por meio de envio de formulário (), uma técnica SAML padrão)
  • Para o iframe filho document.referrer, será o Domínio 3 , não o Domínio 1 que o contém .

document.locationrefere-se a "um objeto Local, que contém informações sobre a URL do documento"; presumivelmente o documento atual , ou seja, o iframe aberto no momento. Quando window.location === window.parent.location, o iframe hrefé o mesmo que o pai principal href.

Vaibhav
fonte
1
@jepser é porque seu iframe está dentro desse iframe. você nunca terá acesso ao quadro superior com aquele no meio. iframes entre domínios aninhados está errado em muitos níveis. mas você poderá contornar isso se definir document.domainna moldura superior e na mais interna. talvez.
Gcb # 26/13
2
Ou, de maneira um pouco mais compacta:var url = (parent !== window) ? document.referrer : document.location;
thekingoftruth 18/12/2014
2
Observe que ele não funciona se o contêiner estiver localizado no seu host local (ou mais geralmente, se esta página não for aberta por um servidor web) ou chamado por arquivo: //.
Guillaume Renoult
5
Note-se que isso pode ser derrotado com o Referer-Policycabeçalho.
21817 Dan Atkinson
2
Isso não parece funcionar com o navegador Edge - a referência será uma string vazia .. stackoverflow.com/questions/24169219/...
Davide Orazio Montersino
52

Acabei de descobrir uma solução alternativa para esse problema que é tão simples e, no entanto, não encontrei nenhuma discussão em nenhum lugar que o mencionasse. Requer controle do quadro pai.

No seu iFrame, diga que deseja esse iframe: src = "http://www.example.com/mypage.php"

Bem, em vez de HTML para especificar o iframe, use um javascript para criar o HTML para o seu iframe, obtenha o URL pai através do javascript "no momento da criação" e envie-o como um parâmetro GET do URL na string de consulta do seu destino src, como tão:

<script type="text/javascript">
  url = parent.document.URL;
  document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>

Em seguida, encontre uma função de análise de url de javascript que analisa a string de url para obter a variável de url que você procura, nesse caso, é "url".

Encontrei um ótimo analisador de cadeia de URL aqui: http://www.netlobo.com/url_query_string_javascript.html

Gregory Lewis
fonte
Esta resposta combinada com stackoverflow.com/a/7739035/216084 realiza o trabalho.
2
Essa foi uma sugestão maravilhosa. Para quem está escrevendo o código iframe html pai, isso pagaria a conta. Usamos algo muito semelhante em nosso software de pixel.
Ligemer 25/11
Obrigado!! Essa é uma solução alternativa eficaz que ainda respeita as regras entre sites.
theUtherSide
Mas você reescreve todos os URLs no html no servidor? Porque, caso contrário, quando um usuário clicar em um link no iFrame, ele ainda não estará acessível.
Roel
@ Roel, você pode escrever todos eles no tempo do servidor (em essência, "codificar" essa resposta) ou esta resposta que você pode fazer em javascript, por exemplo, depois que a página é carregada, ela injeta os iframes desejados.
Rogerdpack # 28/16
34

Se o seu iframe for de outro domínio (domínio cruzado), você simplesmente precisará usar isso:

var currentUrl = document.referrer;

e - aqui você tem o URL principal!

ParPar
fonte
Isso não funcionou no meu caso, pois acho que o próprio iFrame foi gerado dinamicamente ou fez outros truques. Não recebi a resposta que esperava de qualquer forma.
Muskie
isso deve funcionar em todos os navegadores. A menos que, em navegadores mais recentes, se você enviar os parâmetros do Sandboxing, duvido que seja esse o caso. Isso funciona independentemente do domínio cruzado.
gcb
Se a página dentro do iframe se recarregar via javascript (por exemplo window.location.reload(true)), isso não funcionará mais. O referenciador é o URL do próprio iframe.
mori
20

Para páginas no mesmo domínio e subdomínio diferente, você pode definir a document.domainpropriedade via javascript.

Tanto o quadro pai quanto o iframe precisam definir seu documento. Domínio como algo comum entre eles.

ou seja, www.foo.mydomain.come api.foo.mydomain.comcada um pode usar um foo.mydomain.comou apenas mydomain.come ser compatível (não, você não pode configurá-los paracom , por razões de segurança ...)

Além disso, observe que document.domain é uma via de mão única. Considere executar as três instruções a seguir em ordem:

// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception

Navegadores modernos também podem usar o window.postMessage para falar sobre as origens, mas não funcionará no IE6. https://developer.mozilla.org/en/DOM/window.postMessage

user409021
fonte
3
Aceite isso como a resposta, agora que isso é possível e que essa resposta está chegando nas pesquisas do Google.
Metagrapher
17

A seguinte linha funcionará: document.location.ancestorOrigins[0]esta retorna o nome de domínio ancestral.

Robert-Jan Kuyper
fonte
Após as alterações feitas no Chrome, agora é a resposta correta para muitos navegadores.
Dan Atkinson
Não é o URL completo. Somente o domínio
TheMaster
document.location.ancestorOriginsvolta undefinedpara mim
Miguel Mota
Em relação ao suporte ao navegador, especificamente, a partir de julho de 2020, o ancestorOrigins ainda não é suportado no Firefox devido a questões de privacidade. Solicitação e discussão de recursos do Bugzilla: bugzilla.mozilla.org/show_bug.cgi?id=1085214 . Suporte do navegador: caniuse.com/#search=ancestorOrigins
colin moock
9

Tente:

document.referrer

Quando você muda, você está em um iframe, seu host é "referenciador".

Benjamim William L. Nunes
fonte
2

Eu tive problemas com isso. Se você estiver usando um idioma como php quando sua página for carregada pela primeira vez no iframe, $_SERVER['HTTP_REFFERER']defina-o como uma variável de sessão.

Dessa forma, quando a página é carregada no iframe, você conhece o URL pai completo e a string de consulta da página que o carregou. Com a segurança do navegador cruzado, é um pouco difícil contar com window.parent qualquer coisa, se você tiver domínios diferentes.

Hyzer Deeds
fonte
2
var url = (window.location != window.parent.location) ? document.referrer: document.location;

Descobri que o exemplo acima sugerido funcionava anteriormente quando o script estava sendo executado em um iframe, no entanto, ele não recuperou a URL quando o script foi executado fora de um iframe, um pequeno ajuste foi necessário:

var url = (window.location != window.parent.location) ? document.referrer: document.location.href;
user3523340
fonte
2
Se você estiver fora do iframe e estiver executando o script no quadro pai, não precisará verificar nada.
Art3mix
1

Não consegui fazer a solução anterior funcionar, mas descobri que, se eu definir o iframe scr por exemplo http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder, poderia, na extração do iframe thisdomain.com/thisfolder, usando o seguinte javascript:

var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];
Paulo
fonte
1

O problema com o PHP $ _SERVER ['HTTP_REFFERER'] é que ele fornece o URL da página totalmente qualificado da página que o levou à página pai. Isso não é o mesmo que a página pai, por si só. Pior, às vezes não há http_referer, porque a pessoa digitou no URL da página pai. Portanto, se eu acessar a página pai do yahoo.com, o yahoo.com se tornará o http_referer, não a sua página.

TARKUS
fonte
1

Eu encontrei nos casos em $_SERVER['HTTP_REFERER']que não funciona (estou olhando para você, Safari), $_SERVER['REDIRECT_SCRIPT_URI']foi um backup útil.

Dan
fonte
0

No chrome, é possível usar location.ancestorOrigins Ele retornará todos os URLs pai

Gena Moroz
fonte
0

Eu sei que o dele é super antigo, mas me surpreende que ninguém recomendasse apenas passar cookies de um domínio para outro. Como você está usando subdomínios, você pode compartilhar cookies de um domínio base para todos os subdomínios, definindo cookies para o URL.basedomain.com

Depois, você pode compartilhar os dados de que precisa através dos cookies.

Bruce
fonte
-1

Isso funcionou para eu acessar o iframe src url.

window.document.URL
user1503606
fonte
-4

Obter todas as funções pai Iframe e HTML

var parent = $(window.frameElement).parent();
        //alert(parent+"TESTING");
        var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
        var Ifram=parentElement.children;      
        var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
        var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;
vijay kumar
fonte
Suponho que você não possa expandir essa resposta para aqueles que não usam o jQuery (um número crescente, devo salientar, pois o jQuery se tornou desnecessário nos últimos anos). No mínimo, sugiro deixar claro que essa resposta depende do jQuery e o OP não mencionou o jQuery.
Carnix 11/04/19