Can't access an about:blank iframe in IE after the document.domain changes
Asked Answered
H

3

10

Does anyone know of any workarounds to creating an about:blank iframe on a page in IE when the document.domain has changed?

IE doesn't seem to allow access to empty/dynamic iframes after the document.domain property has been altered.

For example, imagine you're dynamically creating an iframe and then injecting some html into it:

// Somewhere else, some 3rd party code changes the domain 
// from something.foo.com to foo.com 
document.domain = 'jshell.net';

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);

// In IE, we can't access the iframe's contentWindow! Access is denied.
iframe.contentWindow.document.body.style.backgroundColor = 'red';

Here's a live example on jsfiddle: http://jsfiddle.net/XHkUT/

You'll notice it works fine in FF/Webkit, but not IE. It's particularly frustrating because this affects iframes created after the document.domain property has changed (as in the example above).

The IE rule seems to be "if you create a dynamic/empty iframe after you change document.domain, you can't access its DOM."

Setting the iframe src to about:blank javascript:void(0) or javascript:"" has been unsuccessful.

Hornpipe answered 5/2, 2013 at 19:33 Comment(2)
The about: protocol may be restricted depending on IE settings/version: msdn.microsoft.com/en-us/library/ee330729(v=vs.85).aspx (see 'About Protocol Restriction' chapter)Arsenical
Note: This bug appears to be fixed in IE11.Phira
A
5

Are you happy to change the domain of the iframe to? The following works (for me) in IE7,9

document.domain = 'jshell.net';

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.src = "javascript:document.write('<script>document.domain=\"jshell.net\"</script>')";

// Now write some content to the iframe
iframe.contentWindow.document.write('<html><body><p>Hello world</p></body></html>');

Edit: If this is inline script on a page then you need to split the closing </script> tag up. See why-split-the-script-tag

Aureole answered 14/2, 2013 at 11:56 Comment(4)
This works, thanks. It also seems to work nicely in FF/Webkit. You'll need to break apart the <script> tags in the src string, though: jsfiddle.net/gHxjL/4Hornpipe
Yes, you will need to split the closing script tag if the code is an inline script in the page. I've updated the answer.Aureole
There's a great article about this issue (and what Facebook did) here: lognormal.com/blog/2012/12/12/the-script-loader-patternHornpipe
Sadly, lognormal is gone. Archive.org link: web.archive.org/web/20130308235154/http://www.lognormal.com/… See the "Cross-domain issues" section at the bottom.Phira
L
0

I've always worked around issues like this by setting the iframe's src to a blank file that lives on the same domain as the parent's domain. If it's possible to create such a file on jshell.net, I would recommend something like:

var iframe = document.createElement('iframe');
iframe.src = 'http://jshell.net/blank.html';
document.body.appendChild(iframe);

Where blank.html just contains a little boilerplate, for example:

<html><head><title>about:blank</title><head><body></body></html>
Leeway answered 11/2, 2013 at 18:6 Comment(1)
Unfortunately, there isn't write access to the domain the script is hosted on (the Javascript code itself is a widget that needs to run everywhere).Hornpipe
H
0

If the iframe.src and document.location are on different domains (or subdomains) you by definition do not have access from the parent to the child. However, you have access from the child to the parent. One of the techniques used when loading cross-domain JavaScript is using the fact that the iframe can call a method in the container window when loaded.

Only if the two documents are on different subdomains, you may tweak the document.domain to match the domain of the iframe.src to enable access.

Read more about same origin policy here:

http://en.wikipedia.org/wiki/Same_origin_policy

http://softwareas.com/cross-domain-communication-with-iframes

Hummer answered 14/2, 2013 at 9:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.