在文档域改变后,无法在IE中访问about:blank的iframe

10

在文档域已更改时,是否有任何解决方法可以在IE中创建一个about:blank iframe?

document.domain属性被更改后,IE似乎不允许访问空/动态iframe。

例如,假设您正在动态创建一个iframe,然后将一些html注入其中:

// 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';

这里有一个在 jsfiddle 上的实时示例:http://jsfiddle.net/XHkUT/

你会发现它在 FF/Webkit 中正常工作,但在 IE 中不行。这特别令人沮丧,因为它会影响在更改了 document.domain 属性之后创建的 iframe(就像上面的示例一样)。

IE 的规则似乎是“如果在更改了 document.domain 后创建了一个动态/空 iframe,则无法访问其 DOM。”

将iframe的src设置为about:blankjavascript:void(0)javascript:"" 都没有成功。


about: 协议可能会受到IE设置/版本的限制:http://msdn.microsoft.com/en-us/library/ee330729(v=vs.85).aspx(请参阅“关于协议限制”章节) - Simon Mourier
1
注意:此错误似乎已在IE11中修复。 - EricLaw
3个回答

5
你愿意更改 iframe 的域名吗?以下方法(对我来说)在 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>');

编辑:如果这是页面上的内联脚本,则需要拆分关闭的</script>标记。请参见为什么要拆分脚本标记


这个有效,谢谢。它看起来在FF/Webkit中也很好用。不过你需要拆开src字符串中的<script>标签:http://jsfiddle.net/gHxjL/4/ - smithclay
是的,如果代码是页面上的内联脚本,您需要拆分闭合脚本标记。我已更新答案。 - Sean Hogan
这个问题有一篇很棒的文章(以及Facebook所做的事情),在这里:http://www.lognormal.com/blog/2012/12/12/the-script-loader-pattern/ - smithclay
很遗憾,lognormal已经消失了。存档链接:https://web.archive.org/web/20130308235154/http://www.lognormal.com/blog/2012/12/12/the-script-loader-pattern/ 请查看底部的“跨域问题”部分。 - EricLaw

0

我通常通过将iframe的src设置为与父域相同的空文件来解决此类问题。如果在 jshell.net 上可以创建这样的文件,我建议使用以下内容:

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

其中blank.html只包含一些样板文件,例如:

<html><head><title>about:blank</title><head><body></body></html>

很不幸,脚本所在的域名没有写入权限(JavaScript代码本身是需要在任何地方运行的小部件)。 - smithclay

0

如果iframe.src和document.location位于不同的域(或子域),则您从父级到子级没有访问权限。但是,您可以从子级到父级进行访问。加载跨域JavaScript时使用的技术之一是利用iframe在加载时可以调用容器窗口中的方法。

只有当两个文档位于不同的子域上时,您才可以调整document.domain以匹配iframe.src的域,以启用访问。

在此处阅读有关同源策略的更多信息:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接