Cross-Origin Frame

Cross-Origin Frame, o que é isso?

Se você é um desenvolvedor web e já tentou utilizar iframe para alguma finalidade, é possível que você tenha visto a seguinte mensagem de erro do cross-origin frame.

SecurityError: Blocked a frame with origin "http://www.<domain>.com" from accessing a cross-origin frame.

[caption id=”attachment_1066" align=”aligncenter” width=”679"]

Erro Cross-Origin Frame

Erro Cross-Origin Frame[/caption]

A mensagem que você ve sobre o cross-origin frame é exibida devido a violação de segurança conhecida como Same-origin policy. O browser permite que uma determinada página acesse dados de outra página somente quando elas são da mesma origem, a origem é definida pela seguinte combinação:

(Esquema da URL[http|https])://(nome do host):(número da porta)

Exemplos

URL Esquema Nome do host Número da porta http://www.meudominio.com.br http www.meudominio.com.br 80 http://www.meudominio.com.br:8080 http www.meudominio.com.br 8080 http://www.meudominio.com.br/home/index http www.meudominio.com.br 80 https://www.meudominio.com.br/home/index https www.meudominio.com.br 80 https://app.meudominio.com.br/home/index https app.meudominio.com.br 80 https://meudominio.com.br/home/index https meudominio.com.br 80

Basicamente essa política de segurança previne que um script malicioso de uma página acesse dados privados de outra página através do DOM.

Como resolver Cross-Origin Frame

Certa vez, tive a necessidade de realizar uma comunicação entre um iframe e a página que continha esse iframe, as duas páginas eram minhas, e para resolver esse problema por meio da solução que vou explicar aqui, é necessário que você seja o dono de ambos os recursos.

Para resolver isso, eu usei a propriedade domain que pertence ao document, ela permite que eu defina qual é o domínio do script por meio de uma string, vamos ver como ficou.

Página principal

A minha página principal possui o seguinte endereço http://crossiframesample1.s3-website-sa-east-1.amazonaws.com/, ela é bem simples, um HTML com um H1 e o iframe, junto a essa página eu carreguei um arquivo javascript, que nele eu defino uma função chamada doAlert dentro da window, veja o código abaixo:

[gist id = “b525001263efcceb7f6cd9bb86a15b9d” file = “mainpage.html” width = “100%” height = “100%”]

Veja que na linha 13 eu defino o iframe onde o src dele é http://crossiframesample2.s3-website-sa-east-1.amazonaws.com/, e de acordo com o padrão de definição da origem, podemos concluir que essas duas origens são diferentes, pois o que muda nesse caso é o nome do host.

[gist id = “b525001263efcceb7f6cd9bb86a15b9d” file = “mainscript.js” width = “100%” height = “100%”]

A primeira linha desse javascript, seta o valor da propriedade domain do document, e vai ser por meio dela que o script que vai ser carregado dentro do iframe vai poder acessar a função doAlert sem que aconteça o erro de cross-origin frame.

Página iframe

A página do iframe está nesse endereço http://crossiframesample2.s3-website-sa-east-1.amazonaws.com/ o seu HTML é bem simples, possui apenas um H1, e essa página também carrega um arquivo javascript, que nele eu defino uma propriedade chamada alberto dentro da window e uma função que é executada por meio da função setTimeout na qual ela chama o método doAlert da window.parent, veja o código abaixo:

[gist id = “b525001263efcceb7f6cd9bb86a15b9d” file = “iframe.html” width = “100%” height = “100%”]

Essa página não possui nenhum segredo, é um html bem simples, que carrega o script após o body.

[gist id = “b525001263efcceb7f6cd9bb86a15b9d” file = “iframescript.js” width = “100%” height = “100%”]

Da mesma forma que no javascript da página principal, também defino na primeira linha o valor da propriedade domain, e logo em seguida defino o objeto alberto como uma propriedade da window. Na linha 11 por meio da função setTimeout faço com que a minha função seja executadas após 2 segundos. Na linha 12 você pode ver que crio uma variável chamada parent que guarda o valor de window.parent, que é a janela que contém o iframe, a nossa página principal. Logo em seguida, na linha 13, eu chamo a função doAlert, passando window.alberto, e após isso altero a cor e o conteúdo do h1 da página.

Uma observação importante é que se você acessar a página que é carregada dentro do iframe em outra aba do browser, a alteração da cor e conteúdo do h1 não vai ocorrer, pois o script vai falhar na linha 13, pois nesse contexto, o window.parent é a própria window, ou seja, quando você chega no topo da árvore de windows, o valor parent da window, é ela mesma, para confirmar isso você pode executar esse trecho de código:

window.parent === window

Ao executar esse código você verá que o resultado é true.

Conclusão

Ao abrir a página principal, após 2 segundos você verá um alert com a mensagem “Ola eu sou Alberto e tenho 26 anos.” e após clicar em ok, tanto o elemento h1 que está na página principal quando o h1 do iframe são alterados. Dessa forma, foi possível executar uma função na página principal que foi definida em um script que é carregado em outra origem de outra página.

Se você já passou por isso e resolveu de outra forma, deixa seu comentário!!!

Vou ficando por aqui, um grande abraço!