Política de mesma origem
Você não pode acessar um <iframe>
com origem diferente usando JavaScript, seria uma enorme falha de segurança se você pudesse fazê-lo. Para os navegadores de política de mesma origem, os scripts de bloqueio tentam acessar um quadro com uma origem diferente .
A origem é considerada diferente se pelo menos uma das seguintes partes do endereço não for mantida:
<protocol>://<hostname>:<port>/...
Protocolo , nome do host e porta devem ser iguais ao seu domínio, se você quiser acessar um quadro.
NOTA: Sabe-se que o Internet Explorer não segue rigorosamente esta regra, consulte aqui para obter detalhes.
Exemplos
Aqui está o que aconteceria ao tentar acessar os seguintes URLs em http://www.example.com/home/index.html
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html:80 -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname
Gambiarra
Embora a política de mesma origem impeça os scripts de acessar o conteúdo de sites com uma origem diferente, se você possui as duas páginas, poderá solucionar esse problema usando window.postMessage
e seu message
evento relativo para enviar mensagens entre as duas páginas, desta forma:
Na sua página principal:
let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
O segundo argumento para postMessage()
pode ser '*'
para não indicar preferência sobre a origem do destino. Uma origem de destino sempre deve ser fornecida quando possível, para evitar a divulgação dos dados que você envia para qualquer outro site.
No seu <iframe>
(contido na página principal):
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://your-first-site.com')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
Esse método pode ser aplicado nas duas direções , criando também um ouvinte na página principal e recebendo respostas do quadro. A mesma lógica também pode ser implementada em pop-ups e basicamente qualquer nova janela gerada pela página principal (por exemplo, usando window.open()
) também, sem nenhuma diferença.
Desativando a política de mesma origem no seu navegador
Já existem boas respostas sobre esse tópico (acabei de encontrá-las no Google). Portanto, para os navegadores onde isso for possível, vincularemos a resposta relativa. No entanto, lembre-se de que desativar a política de mesma origem afetará apenas o seu navegador . Além disso, a execução de um navegador com configurações de segurança da mesma origem desabilitadas concede a qualquer site acesso a recursos de origem cruzada, portanto , é muito inseguro e NUNCA deve ser feito se você não souber exatamente o que está fazendo (por exemplo, fins de desenvolvimento) .
Access-Control-Allow-Origin
não se aplica aos iFrames, apenas aos XHRs, Fonts, WebGL ecanvas.drawImage
. Eu acredito quepostMessage
é a única opção.iframe.src
e, se o site for diferente do nome do host do seu domínio, você não poderá acessar esse quadro.~
retorna o complemento 2 do número,n
tornando - se-n-1
, o que significa que apenas-1
se tornará0
(que é interpretado comofalse
) e que qualquer outro valor passará no teste. Ou seja0 = -(-1)-1
, não-(-1+1)
.location.ancestorOrigins[0]
é o local do quadro pai. Se o seu quadro estiver sendo executado em outro site e você verificar usando,event.origin.indexOf(location.ancestorOrigins[0])
está verificando se a origem do evento contém o endereço do quadro dos pais, o que sempre serátrue
, portanto, você está permitindo que qualquer pai com qualquer origem acesse seu quadro, e isso obviamente não é algo que você deseja fazer. Além disso,document.referrer
é uma prática ruim também, como já expliquei nos comentários acima.Complementando a resposta de Marco Bonelli: a melhor maneira atual de interagir entre quadros / iframes está usando
window.postMessage
, suportada por todos os navegadoresfonte
window.postMessage
funciona duplicaria apenas a resposta aceita, que eu já mencionei. Além disso, o valor essencial que minha resposta agrega é exatamente o de referenciar documentação externa.Verifique a
http://www.<domain>.com
configuração do servidor Web do domínio.X-Frame-Options
É um recurso de segurança projetado para impedir ataques de clickJacking,Como funciona o clickJacking?
Tecnicamente, o mal tem uma
iframe
fonte na página da vítima.Como o recurso de segurança funciona
Se você deseja impedir que a solicitação do servidor da Web seja renderizada em um campo,
iframe
adicione as opções x-frameAs opções são:
Este é o exemplo de configuração do IIS:
A solução para a pergunta
Se o servidor da Web ativou o recurso de segurança, ele pode causar um SecurityError do lado do cliente como deveria.
fonte
Para mim, eu queria implementar um handshake bidirecional, o que significa:
- a janela pai carregará mais rápido que o iframe
- o iframe deve conversar com a janela pai assim que
estiver pronto - o pai está pronto para receber a mensagem e a repetição do iframe
esse código é usado para definir etiqueta branca no iframe usando o código [CSS custom property]
:
iframe
pai
naturalmente, você pode limitar as origens e o texto; este é um código fácil de trabalhar;
achei este exame útil:
[Mensagens entre domínios com postMessage]
fonte
Gostaria de adicionar uma configuração específica do Java Spring que possa afetar isso.
No site ou aplicativo de gateway, há uma configuração contentSecurityPolicy
no Spring, você pode encontrar a implementação da subclasse WebSecurityConfigurerAdapter
...
O navegador será bloqueado se você não definir aqui o conteúdo externo seguro.
fonte
Se você tiver controle sobre o conteúdo do iframe, ou seja, se ele for carregado apenas em uma configuração de origem cruzada, como no Amazon Mechanical Turk, poderá contornar esse problema com o
<body onload='my_func(my_arg)'>
atributo do html interno.Por exemplo, para o html interno, use o
this
parâmetro html (yes -this
é definido e se refere à janela pai do elemento do corpo interno):<body onload='changeForm(this)'>
No html interno:
fonte
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
fonte