How to get the body's content of an iframe in Javascript?
Asked Answered
A

13

192
<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>

What I want to get is:

test<br/>
Acquaint answered 29/5, 2009 at 16:30 Comment(3)
Important note: You can't access the contents of an iFrame if it's cross-domain. See Same-Origin policy.Conjunctivitis
What I find wired is that browsers don't recognize as same origin (so do not authorize to work together) two files I put into the same directory on a local drive. In fact is out of my comprehension why two files that are both into c:/mypath/ and are called main.html and insideiframe.html are an issue for browsers if they access, comunicate or get data or content from each other. I do understand the issue if they were one in adomain.com and the other in anotherdomain.com but in my own local drive and even into the same local directory... that's seems more like an overkillClaireclairobscure
@willywonka Because browser security is a joke. Hack piled upon hack piled upon hack. Look at the mess that is CORS and CSP. None of this is designed to protect the user. It's designed to let web hosts control your browser. W3C is a sham to entrench big players. Local files are just collateral damage.Brazenfaced
T
195

The exact question is how to do it with pure JavaScript not with jQuery.

But I always use the solution that can be found in jQuery's source code. It's just one line of native JavaScript.

For me it's the best, easy readable and even afaik the shortest way to get the iframes content.

First get your iframe

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

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

And then use jQuery's solution

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

It works even in the Internet Explorer which does this trick during the contentWindow property of the iframe object. Most other browsers uses the contentDocument property and that is the reason why we proof this property first in this OR condition. If it is not set try contentWindow.document.

Select elements in iframe

Then you can usually use getElementById() or even querySelectorAll() to select the DOM-Element from the iframeDocument:

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

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

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

Call functions in the iframe

Get just the window element from iframe to call some global functions, variables or whole libraries (e.g. 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 /*, ... */);

Note

All this is possible if you observe the same-origin policy.

Turkish answered 19/6, 2012 at 19:26 Comment(5)
iframe is undefined here, either you should write full code or should not write jQuery with itSniggle
please excuse me, but the line of code is an excerpt from the jquery code and the code block is my own example code. The rest should anyone get himself out. the only thing you are missing is the variable iframe. And I can't possibly know where your iframe is or how its ID is.Turkish
Could you please add a warning to the top of the answer that this does not work if the iframe has a remote src? If I'm wrong, I'd appreciate if you could point me to how I can still get the iframe content without sending another HTTP request (not possible because I need javascript executed to construct the iframe content and don't want to deploy a second javascript environment if avoidable).Probe
I have such a warning. But at the end of my explanation. You have to observe the same-origin policy. That's all.Turkish
To get the above working, I had to enclose it in document.querySelector('#id_description_iframe').onload = function() {... Hope it helps someone.Warty
D
74

Using JQuery, try this:

$("#id_description_iframe").contents().find("body").html()
Dante answered 26/1, 2010 at 17:5 Comment(2)
It doesn't work because the "Domains, protocols and ports must match.": Unsafe JavaScript attempt to access frame with URLSpoonerism
As mentioned, it would work if the domains match. FYI, I've just found that $("#id_description_iframe #id_of_iframe_body").html() does work in Chrome but doesn't in all firefox versions, and hence using the above is fine. I.e. $("#id_description_iframe #id_of_iframe_body").contents().find("body").html() did work in bothWoodman
M
60

it works perfectly for me :

document.getElementById('iframe_id').contentWindow.document.body.innerHTML;
Martellato answered 27/5, 2012 at 5:51 Comment(3)
It's strange, but for me .body does not work. However .getElementsByTagName('body')[0] does.Grearson
its not ".body", just "body". remove the dotCurnin
this should be the answer if you are in to vanilla javascript.Gloxinia
D
26

AFAIK, an Iframe cannot be used that way. You need to point its src attribute to another page.

Here's how to get its body content using plane old javascript. This works with both IE and 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);
 }
Demilitarize answered 29/5, 2009 at 16:52 Comment(2)
it does on safari (ie branch)Pyrogallate
having cross domain issue, Blocked a frame with origin "someOther.com" from accessing a cross-origin frame.Sangraal
L
10

use content in iframe with JS:

document.getElementById('id_iframe').contentWindow.document.write('content');
Louislouisa answered 19/11, 2011 at 14:7 Comment(0)
A
4

I think placing text inbetween the tags is reserved for browsers that cant handle iframes i.e...

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

You use the 'src' attribute to set the source of the iframes html...

Hope that helps :)

Adenaadenauer answered 29/5, 2009 at 16:37 Comment(0)
S
4

Chalkey is correct, you need to use the src attribute to specify the page to be contained in the iframe. Providing you do this, and the document in the iframe is in the same domain as the parent document, you can use this:

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

Obviously you can then do something useful with the contents instead of just putting them in an alert.

Simms answered 29/5, 2009 at 16:48 Comment(0)
S
2

The following code is cross-browser compliant. It works in IE7, IE8, Fx 3, Safari, and Chrome, so no need to handle cross-browser issues. Did not test in 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>
Slipnoose answered 2/3, 2010 at 0:0 Comment(2)
The html below worked for me in Chrome 7 on Mac. I tested this original post in Chrome 6 on Windows and it worked fine. <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>testing</h1>"; } </script> </body> </html>Slipnoose
window.frames.iframeId.document is undefined for me. (Ubuntu 13.04, Chrome)Spoonerism
H
2

To get body content from javascript ,i have tried the following code:

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

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

where "id_description_iframe" is your iframe's id. This code is working fine for me.

Hydrometeor answered 16/1, 2020 at 6:5 Comment(2)
Please put your answer always in context instead of just pasting code. See here for more details.Bialystok
Code-only answers are considered low quality: make sure to provide an explanation what your code does and how it solves the problem. It will help the asker and future readers both if you can add more information in your post. See also Explaining entirely code-based answers: meta.stackexchange.com/questions/114762/…Strohl
P
2

You can get the contents of the iframe body in one line of code:

document.getElementsByTagName('iframe')[0].contentWindow.document.body.innerText;
Prosperus answered 23/4, 2021 at 17:11 Comment(0)
S
2

If you want to not just select the body of your iframe, but also insert some content to it, and do that with pure JS, and with no JQuery, and without document.write(), I have a solution that no other answer provides.

You can use the following steps

1.Select your iframe:

var iframe = document.getElementById("adblock_iframe");

2.Create an element that you want to insert into the frame, let's say an image:

var img = document.createElement('img');
img.src = "https://server-name.com/upload/adblock" + id + ".jpg";
img.style.paddingLeft = "450px";
//scale down the image is we have a high resolution screen on the client side
if (retina_test_media == true && high_res_test == true) {
    img.style.width = "200px";
    img.style.height = "50px";
} else {
    img.style.width = "400px";
    img.style.height = "100px";
}
img.id = "image";

3.Insert the image element into the iframe:

iframe.contentWindow.document.body.appendChild(img);
Shonda answered 30/7, 2021 at 15:16 Comment(0)
S
1

Most of the answers given are correct, but you should not forget that an iframe is rendered separately from the main document, and that takes some time: do not expect a script in your main document to be able to immediately access a document in an iframe: it will only return an empty document.

Make sure you put code which is going to deal with an iframe in a document.body.onload function in your main document.

Swope answered 23/2 at 12:7 Comment(0)
H
0
const iframe1 = document.getElementById('iframe1');
const iframeContent = iframe1.contentWindow.document.body.innerHTML;

const iframeContentDiv = document.createElement('div');
iframeContentDiv.innerHTML = iframeContent;

document.body.appendChild(iframeContentDiv);
Hearttoheart answered 11/10, 2023 at 12:44 Comment(1)
Welcome to SO! Please properly format your code and add some explanation to it.Corrosive

© 2022 - 2024 — McMap. All rights reserved.