¿Cómo obtener el contenido del cuerpo de un iframe en Javascript?

154
<iframe id="id_description_iframe" class="rte-zone" height="200" frameborder="0" title="description">
  <html>
    <head></head>
    <body class="frameBody">
      test<br/>
    </body>
  </html>
</iframe>

Lo que quiero obtener es:

test<br/>
Dios mio
fuente
52
Nota importante: no puede acceder al contenido de un iFrame si es de dominio cruzado. Ver la política del mismo origen .
HellaMad

Respuestas:

154

La pregunta exacta es cómo hacerlo con JavaScript puro, no con jQuery.

Pero siempre uso la solución que se puede encontrar en el código fuente de jQuery. Es solo una línea de JavaScript nativo.

Para mí es el mejor, fácil de leer e incluso afaik la forma más corta de obtener el contenido de los iframes.

Primero obtenga su iframe

var iframe = document.getElementById('id_description_iframe');

// or
var iframe = document.querySelector('#id_description_iframe');

Y luego usa la solución de jQuery

var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;

Funciona incluso en Internet Explorer que hace este truco durante la contentWindowpropiedad del iframeobjeto. La mayoría de los otros navegadores usan la contentDocumentpropiedad y esa es la razón por la que primero probamos esta propiedad en esta condición OR. Si no está configurado, intente contentWindow.document.

Seleccionar elementos en iframe

Luego, generalmente puede usar getElementById()o incluso querySelectorAll()seleccionar el elemento DOM de iframeDocument:

if (!iframeDocument) {
    throw "iframe couldn't be found in DOM.";
}

var iframeContent = iframeDocument.getElementById('frameBody');

// or
var iframeContent = iframeDocument.querySelectorAll('#frameBody');

Funciones de llamada en el iframe

Obtenga solo el windowelemento de iframepara llamar a algunas funciones globales, variables o bibliotecas completas (por ejemplo jQuery):

var iframeWindow = iframe.contentWindow;

// you can even call jQuery or other frameworks
// if it is loaded inside the iframe
iframeContent = iframeWindow.jQuery('#frameBody');

// or
iframeContent = iframeWindow.$('#frameBody');

// or even use any other global variable
iframeWindow.myVar = window.myVar;

// or call a global function
var myVar = iframeWindow.myFunction(param1 /*, ... */);

Nota

Todo esto es posible si observa la política del mismo origen .

algoritmo
fuente
2
el iframe no está definido aquí, o bien debe escribir el código completo o no debe escribir jQuery con él
Tarun Gupta
13
discúlpeme, pero la línea de código es un extracto del código jquery y el bloque de código es mi propio código de ejemplo. El resto si alguien se sale. lo único que falta es la variable iframe. Y no puedo saber dónde está su iframe o cómo es su ID.
algoritmo
55
¿Podría agregar una advertencia en la parte superior de la respuesta de que esto no funciona si el iframe tiene un src remoto? Si me equivoco, agradecería que me indicara cómo puedo obtener el contenido del iframe sin enviar otra solicitud HTTP (no es posible porque necesito que JavaScript se ejecute para construir el contenido del iframe y no quiero implementar un segundo entorno javascript si es evitable).
Zackline el
1
Tengo tal advertencia. Pero al final de mi explicación. Debe observar la política del mismo origen. Eso es todo.
algoritmo el
2
Para que funcione lo anterior, tuve que incluirlo en document.querySelector('#id_description_iframe').onload = function() {... Hope, que ayuda a alguien.
user3442612
71

Usando JQuery, intente esto:

$("#id_description_iframe").contents().find("body").html()
Michael Adedayo
fuente
27
No funciona porque los "Dominios, protocolos y puertos deben coincidir". : JavaScript
no seguro
2
Como se mencionó, funcionaría si los dominios coinciden. Para su información, acabo de encontrar que $ ("# id_description_iframe #id_of_iframe_body"). Html () funciona en Chrome pero no en todas las versiones de Firefox, y por lo tanto, usar lo anterior está bien. Es decir, $ ("# id_description_iframe #id_of_iframe_body"). Contents (). Find ("body"). Html () funcionó en ambos
hobailey
41

Funciona perfectamente para mí :

document.getElementById('iframe_id').contentWindow.document.body.innerHTML;
bizzr3
fuente
3
Es extraño, pero para mí .bodyno funciona. Sin embargo lo .getElementsByTagName('body')[0]hace.
Jenny O'Reilly
no es ".body", solo "cuerpo". quitar el punto
Arjun
1
Esta debería ser la respuesta si estás en JavaScript vainilla.
Jovanni G
23

AFAIK, un Iframe no se puede usar de esa manera. Debe apuntar su atributo src a otra página.

Aquí le mostramos cómo obtener el contenido de su cuerpo usando JavaScript antiguo plano. Esto funciona tanto con IE como con Firefox.

function getFrameContents(){
   var iFrame =  document.getElementById('id_description_iframe');
   var iFrameBody;
   if ( iFrame.contentDocument ) 
   { // FF
     iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
   }
   else if ( iFrame.contentWindow ) 
   { // IE
     iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
   }
    alert(iFrameBody.innerHTML);
 }
Jose basilio
fuente
1
lo hace en safari (es decir, rama)
Andrei Cristian Prodan
teniendo un problema de dominio cruzado, bloqueó un marco con origen " someOther.com " para que no acceda a un marco de origen cruzado.
lannyf
10

utilizar contenten iframe con JS:

document.getElementById('id_iframe').contentWindow.document.write('content');
CursosWeb
fuente
5

Creo que colocar texto entre las etiquetas está reservado para los navegadores que no pueden manejar iframes, es decir ...

<iframe src ="html_intro.asp" width="100%" height="300">
  <p>Your browser does not support iframes.</p>
</iframe>

Utiliza el atributo 'src' para establecer la fuente de los iframes html ...

Espero que ayude :)


fuente
3

El siguiente código es compatible con todos los navegadores. Funciona en IE7, IE8, Fx 3, Safari y Chrome, por lo que no es necesario manejar problemas entre navegadores. No probé en IE6.

<iframe id="iframeId" name="iframeId">...</iframe>

<script type="text/javascript">
    var iframeDoc;
    if (window.frames && window.frames.iframeId &&
        (iframeDoc = window.frames.iframeId.document)) {
        var iframeBody = iframeDoc.body;
        var ifromContent = iframeBody.innerHTML;
    }
</script>
nekno
fuente
El siguiente html funcionó para mí en Chrome 7 en Mac. Probé esta publicación original en Chrome 6 en Windows y funcionó bien. <html> <head> </head> <body> <iframe id = "iframeId" name = "iframeId"> ... </iframe> <script type = "text / javascript"> var iframeDoc; if (window.frames && window.frames.iframeId && window.frames.iframeId.document) {window.frames.iframeId.document.body.innerHTML = "<h1> prueba </h1>"; } </script> </body> </html>
nekno
1
window.frames.iframeId.documentNo está definido para mí. (Ubuntu 13.04, Chrome)
Ionică Bizău
2

Chalkey es correcto, debe usar el atributo src para especificar la página que se incluirá en el iframe. Siempre que haga esto, y el documento en el iframe esté en el mismo dominio que el documento principal, puede usar esto:

var e = document.getElementById("id_description_iframe");
if(e != null) {
   alert(e.contentWindow.document.body.innerHTML);
}

Obviamente, puede hacer algo útil con los contenidos en lugar de simplemente ponerlos en alerta.

Graham Clark
fuente
1

Para obtener contenido del cuerpo de javascript, probé el siguiente código:

var frameObj = document.getElementById('id_description_iframe');

var frameContent = frameObj.contentWindow.document.body.innerHTML;

donde "id_description_iframe" es la identificación de su iframe. Este código está funcionando bien para mí.

sunakshi
fuente
2
Ponga su respuesta siempre en contexto en lugar de simplemente pegar el código. Ver aquí para más detalles.
gehbiszumeis
1
Las respuestas de solo código se consideran de baja calidad: asegúrese de proporcionar una explicación de lo que hace su código y cómo resuelve el problema. Ayudará tanto al autor de la pregunta como a los futuros lectores si puede agregar más información en su publicación. Consulte también Explicación de respuestas completamente basadas en código: meta.stackexchange.com/questions/114762/…
borchvm