Get DOM content of cross-domain iframe [duplicate]
Asked Answered
G

5

101

I have an iframe for a cross-domain site. I want to read the DOM of the iframe, which I believed was possible because using the inspector, I can even modify the DOM of an iframe. Every way I attempt to read it, however, I run into the same origin policy. All I want, is the content loaded in my local DOM, from the iframe. I thought it would be as simple as $(document.body).find('iframe').html(), but that's returning the empty string.

I really hope there's a way to do this since the work I've been doing for the last several days has been predicated on this being do-able.

Thanks

Gainer answered 29/5, 2011 at 22:47 Comment(1)
Yes, you can do this - see https://mcmap.net/q/64991/-get-value-of-input-field-inside-an-iframeTrichoid
N
104

You can't. XSS protection. Cross site contents can not be read by javascript. No major browser will allow you that. I'm sorry, but this is a design flaw, you should drop the idea.

EDIT

Note that if you have editing access to the website loaded into the iframe, you can use postMessage (also see the browser compatibility)

Nisus answered 29/5, 2011 at 22:58 Comment(7)
if you meant design (flow) flaw, then no, it is not a flaw, this was implemented for security.Allover
In that case i misunderstood thenAllover
In the end, I didnt need to use an iframe for what I was doing.Gainer
good to hear that you could resolve itCrosscrosslet
For reference, cross-domain same-origin-policy means that hostname, port and protocol must all be the same - en.wikipedia.org/wiki/Same-origin_policy (eg app1.example.com and app2.example.com are different; example.com and www.example.com are different)Stefa
Note: You can use window.postMessage to communicate between iframe and the main window.Stefa
CORS is not an option here. It does not enable JS to read the DOM of a cross-origin frame.Sorely
A
26

There is a simple way.

  1. You create an iframe which has for source something like "http://your-domain.com/index.php?url=http://the-site-you-want-to-get.com/unicorn

  2. Then, you just get this url with $_GET and display the contents with file_get_contents($_GET['url']);

You will obtain an iframe which has a domain same than yours, then you will be able to use the $("iframe").contents().find("body") to manipulate the content.

Arapaima answered 28/1, 2016 at 5:48 Comment(5)
Could you please explain the detail. Thank you very much@@Allieallied
Sorry to be late, I didn't noticed. 1. Create a php page that display the content of the page you want from a GET parameter. content.php <?php echo file_get_contents($_GET['url']); ?> 2. Then, in your main page, add an iframe that will load this page. <iframe src="content.php?url=http://google.com"> 3. It will display the wanted page in the iframe. Content.php is from your domain, so you can manipulate the iframe content with JS, without violating cross-origin policy. var $iframeBody = $("iframe").contents().find("body"); $iframeBody.css("background", blue");Tb
If for whatever reason you don't want an iframe you could make an ajax call to your php tooChrystel
@Bharata: Wrong. If you load the file contents into an iframe, you can access its inner DOM just like normal same-origin iframe.Philips
Note that if you use this method, be very careful since this will allow your server to be used as a de facto proxy. Therefore this should be behind authentication and/or the list of permitted websites should be restricted.Philips
I
9

If you have access to the iframed page you could use something like easyXDM to make function calls in the iframe and return the data.

If you don't have access to the iframed page you will have to use a server side solution. With PHP you could do something quick and dirty like:

    <?php echo file_get_contents('http://url_of_the_iframe/content.php'); ?> 
Ison answered 29/5, 2011 at 22:52 Comment(5)
i dont have access to the iframed page and a server-side solution is pretty much out of the question, because i am using cocoahttpserver (the server is running on an iphone)Gainer
In that case it's not possible. See en.wikipedia.org/wiki/Same_origin_policy for more detailed info.Ison
You sir are a scholar and a gentlemanOreopithecus
thanks allot for the idea, this answer and this - https://mcmap.net/q/212497/-file_get_contents-fix-relative-urls, helped me create a workaround! cheersMainis
@devmatt, with file_get_contents($_GET['url']) you can get page content, but you can not get DOM content! Wrong answer.Benign
L
7

If you have an access to that domain/iframe that is loaded, then you can use window.postMessage to communicate between iframe and the main window.

Read the DOM with JavaScript in iframe and send it via postMessage to the top window.

More info here: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

Lhary answered 28/8, 2015 at 7:25 Comment(2)
How can we read the DOM in iframe with js? It's possible, isn't it?Indices
You read the DOM as you would normally. For example document.getElementsByTagName("BODY")[0]; After that use the window.postMessage to send the DOM object you just read in the iframed window to the window that is hosting the iframe window.Lhary
R
1

There's a workaround to achieve it.

  1. First, bind your iframe to a target page with relative url. The browsers will treat the site in iframe the same domain with your website.

  2. In your web server, using a rewrite module to redirect request from the relative url to absolute url. If you use IIS, I recommend you check on IIRF module.

Retroactive answered 30/5, 2011 at 4:58 Comment(2)
Do you mean server sends http redirect to foreign location? If so, it doesn't work in at least Firefox 9. I assume other browsers won't be fooled by that eitherGeneralization
He means rewriting the request on the server, so the client has no idea that it isn't the right urlAffecting

© 2022 - 2024 — McMap. All rights reserved.