我有一个包含iframe的窗口,其中包含iframe,如下所示:
+---------------+
| Top |
| +-----------+ |
| | Middle | |
| | +-------+ | |
| | | Inner | | |
| | +-------+ | |
| +-----------+ |
+---------------+
Top和Middle位于同一个域中,但Inner位于不同的域中。我需要Inner与Top交流。我知道这样做的唯一方法是IE7支持(我需要支持)是改变窗口位置的哈希值。但是,我不希望信息在位置栏中闪烁,所以我介绍了中间iframe。
我希望Inner改变Middle的哈希值。 Middle会读取它的哈希并通知Top,它有权直接与之交谈。
然而,在Firefox 3中,我无法从Inner写入Middle的哈希。不会引发错误,但哈希值不会改变。写入location.href
会引发权限错误。
Top可以写入Middle的哈希,然而,Middle可以写入Inner的哈希值,Top可以写入Inner的哈希值,而Inner和Middle都可以写入Top的哈希值,因此只有有序对那不起作用就是我想要的! (我一直在研究这个问题。)
我在最小的测试用例中复制了这个。起初,我在同一个域中提供了所有三个页面。当我将Inner放在不同的域上时,我会遇到有问题的行为。当我将Middle放在第二个域名时,每个人都可以再次写信给所有人。
为什么Inner不能写入Middle的哈希?
附录:很多人都认为,由于同源政策,这不可能实现。这正是我试图解决的政策。这个确切的案例 - 设置(但不是读取)另一个窗口的位置 - 应该可以跨域。我没有找到这种效果的浏览器文档,但我发现了很多文章和演示。这基本上是HTML 5 postMessage()
的前身。
参考:http://softwareas.com/cross-domain-communication-with-iframes
答案 0 :(得分:7)
父框架可以使用以下方式设置子项的iframe'src属性(此处使用jquery):
$("#iframeWindow").attr('src', "http://<CHILD URL>/#hello");
儿童iframe可以使用以下方式设置父窗口的href(地址栏内容):
window.top.location.href = "http://<PARENT URL>/#hello"
并且在父母和/或子女中,您需要轮询更改,
var last = "";
setInterval(function() {
if(last == window.location.href) return;
last = window.location.href;
//do stuff with 'window.location.hash'
}, 1000);
请注意,如果你能
那就太好了window.top.location.href = window.top.location.href + "#hello"
但不允许读取位置对象(href和hash)
于11月3日在chrome上测试,即6/7/9,firefox 3.6 / 4
edit1:如果人们愿意,可以直播演示
edit2:http://dl.dropboxusercontent.com/u/14376395/html/xdomain.html:)
edit3:注意:如果您使用此方法,请确保您可以控制所有iframe页面,否则恶意的第三方网站可能会使用哈希标记来控制您的
edit4:Google JavaScript API目前正在使用的更好的解决方案http://ternarylabs.com/2011/03/27/secure-cross-domain-iframe-communication/
edit5:dropbox域名已更改为“dl.dropboxusercontent.com”
答案 1 :(得分:1)
为了能够设置location.hash,您必须先获取位置。相同的原始政策禁止您获取该位置。
答案 2 :(得分:1)
根据WrocLaw的说法,听起来这是Bugzilla中Firefox的一个错误。
答案 3 :(得分:0)
是否所有框架都包含相同来源的位置? (例如,相同的协议,相同的域,相同的端口)。如果它们不是一个潜在的安全漏洞,如果一个框架可以修改另一个框架 - 谷歌相同的原始政策。但是没有更多细节,很难提供更好的答案。
答案 4 :(得分:0)
我无法回答散列的原因,但您是否看过John Resig的work postMessage
?你遇到FF3问题,FF3恰好是支持postMessage
的浏览器之一,bingo: - )
如果失败了,那就是xssinterface库。似乎很稳定,但我没有亲自尝试过。
答案 5 :(得分:-1)
亚历克斯称这是一个安全问题。如果Inner位于其他域上,则无法访问Top layer。这是为了避免Cross-site Scripting。