origin from cross content accessing javascript jquery iframe same-origin-policy

javascript - from - jquery access iframe content



jQuery/JavaScript: acceder a los contenidos de un iframe (12)

Me gustaría manipular el HTML dentro de un iframe usando jQuery.

Pensé que sería capaz de hacer esto configurando el contexto de la función jQuery para que fuera el documento del iframe, algo como:

$(function(){ //document ready $(''some selector'', frames[''nameOfMyIframe''].document).doStuff() });

Sin embargo, esto no parece funcionar. Un poco de inspección me muestra que las variables en los frames[''nameOfMyIframe''] undefined están undefined menos que espere un momento a que se cargue el iframe. Sin embargo, cuando se carga el iframe, no se puede acceder a las variables (tengo permission denied errores de tipo).

¿Alguien sabe de una solución a esto?


¿Has probado el clásico, esperando a que se complete la carga con la función integrada de jQuery?

$(document).ready(function() { $(''some selector'', frames[''nameOfMyIframe''].document).doStuff() } );

K


Creo que lo que estás haciendo está sujeto a la misma política de origen . Esta debe ser la razón por la que está obteniendo un permiso denegado errores de tipo .


Creo un código de muestra. Ahora puede entender fácilmente desde diferentes dominios que no puede acceder al contenido de iframe. El mismo dominio al que podemos acceder puede acceder a contenido de iframe

Te comparto mi código, por favor ejecuta este código, comprueba la consola. Imprimo imagen src en consola. Hay cuatro iframe, dos iframe que vienen del mismo dominio y otros dos de otro dominio (tercero). Puede ver dos src de imagen ( https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif

y

https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif ) en la consola y también puede ver dos errores de permiso (2 Error: Permiso denegado para acceder al documento de propiedad) ''

... irstChild)}, contents: function (a) {return m.nodeName (a, "iframe")? a.contentDocument ...

) que viene de iframe de terceros.

<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top"> <p>iframe from same domain</p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="iframe.html" name="imgbox" class="iView"> </iframe> <p>iframe from same domain</p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="iframe2.html" name="imgbox" class="iView1"> </iframe> <p>iframe from different domain</p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2"> </iframe> <p>iframe from different domain</p> <iframe frameborder="0" scrolling="no" width="500" height="500" src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3"> </iframe> <script type=''text/javascript''> $(document).ready(function(){ setTimeout(function(){ var src = $(''.iView'').contents().find(".shrinkToFit").attr(''src''); console.log(src); }, 2000); setTimeout(function(){ var src = $(''.iView1'').contents().find(".shrinkToFit").attr(''src''); console.log(src); }, 3000); setTimeout(function(){ var src = $(''.iView2'').contents().find(".shrinkToFit").attr(''src''); console.log(src); }, 3000); setTimeout(function(){ var src = $(''.iView3'').contents().find("img").attr(''src''); console.log(src); }, 3000); }) </script> </body>


Debe adjuntar un evento al controlador de carga de un iframe, y ejecutar el js allí, para asegurarse de que el iframe haya terminado de cargarse antes de acceder a él.

$().ready(function () { $("#iframeID").ready(function () { //The function below executes once the iframe has finished loading $(''some selector'', frames[''nameOfMyIframe''].document).doStuff(); }); };

Lo anterior solucionará el problema ''aún no cargado'', pero en lo que respecta a los permisos, si está cargando una página en el iframe de un dominio diferente, no podrá acceder a ella debido a restricciones de seguridad.


Me parece esta manera más limpia:

var $iframe = $("#iframeID").contents(); $iframe.find(''selector'');


Para aún más robustez:

function getIframeWindow(iframe_object) { var doc; if (iframe_object.contentWindow) { return iframe_object.contentWindow; } if (iframe_object.window) { return iframe_object.window; } if (!doc && iframe_object.contentDocument) { doc = iframe_object.contentDocument; } if (!doc && iframe_object.document) { doc = iframe_object.document; } if (doc && doc.defaultView) { return doc.defaultView; } if (doc && doc.parentWindow) { return doc.parentWindow; } return undefined; }

y

... var frame_win = getIframeWindow( frames[''nameOfMyIframe''] ); if (frame_win) { $(frame_win.contentDocument || frame_win.document).find(''some selector'').doStuff(); ... } ...


Prefiero usar otra variante para acceder. Desde padre puede tener acceso a variable en iframe hijo. $ es una variable también y puede recibir acceso a su simplemente llamada window.iframe_id.$

Por ejemplo, window.view.$(''div'').hide() - oculta todos los divs en iframe con id ''view''

Pero, no funciona en FF. Para una mejor compatibilidad debes usar

$(''#iframe_id'')[0].contentWindow.$


Puede usar window.postMessage para llamar a una función entre la página y su iframe (dominio cruzado o no).

Documentation

page.html

<!DOCTYPE html> <html> <head> <title>Page with an iframe</title> <meta charset="UTF-8" /> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> var Page = { id:''page'', variable:''This is the page.'' }; $(window).on(''message'', function(e) { var event = e.originalEvent; if(window.console) { console.log(event); } alert(event.origin + ''/n'' + event.data); }); function iframeReady(iframe) { if(iframe.contentWindow.postMessage) { iframe.contentWindow.postMessage(''Hello '' + Page.id, ''*''); } } </script> </head> <body> <h1>Page with an iframe</h1> <iframe src="iframe.html" onload="iframeReady(this);"></iframe> </body> </html>

iframe.html

<!DOCTYPE html> <html> <head> <title>iframe</title> <meta charset="UTF-8" /> <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> var Page = { id:''iframe'', variable:''The iframe.'' }; $(window).on(''message'', function(e) { var event = e.originalEvent; if(window.console) { console.log(event); } alert(event.origin + ''/n'' + event.data); }); $(window).on(''load'', function() { if(window.parent.postMessage) { window.parent.postMessage(''Hello '' + Page.id, ''*''); } }); </script> </head> <body> <h1>iframe</h1> <p>It''s the iframe.</p> </body> </html>


Si el <iframe> es del mismo dominio, los elementos son fácilmente accesibles como

$("#iFrame").contents().find("#someDiv").removeClass("hidden");

Reference


Si el iframe src es de otro dominio, todavía puedes hacerlo. Necesitas leer la página externa en PHP y repetirla desde tu dominio. Me gusta esto:

iframe_page.php

<?php $URL = "http://external.com" $domain = file_get_contents($URL) echo $domain ?>

Entonces algo como esto:

display_page.html

<html> <head> <title>Test</title> </head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script> <script> $(document).ready(function(){ cleanit = setInterval ( "cleaning()", 500 ); }); function cleaning(){ if($(''#frametest'').contents().find(''.selector'').html() == "somthing"){ clearInterval(cleanit); $(''#selector'').contents().find(''.Link'').html(''ideate tech''); } } </script> <body> <iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe> </body> </html>

Lo anterior es un ejemplo de cómo editar una página externa a través de un iframe sin el acceso denegado, etc.


Utilizar

iframe.contentWindow.document

en lugar de

iframe.contentDocument


$(document).ready(function(){ $(''#frameID'').load(function(){ $(''#frameID'').contents().find(''body'').html(''Hey, i`ve changed content of <body>! Yay!!!''); }); });