浅析iframe

iframe 提供了一种途径,让我们在一个页面中嵌入另一个页面。有些时候,我们希望两个窗口能够通信。每个窗口都有一个独立的 window 对象,窗口直接的相互通信就是通过 window 对象直接的相互引用来实现的。

重点在最后。

父窗口引用子窗口

frames 属性

父窗口中的 window 对象有一个 frames 的属性,通过它能够访问到其页面上的所有 iframe 的 window 对象。具体有两种方式:

window.frames[0]  // 通过下标为数字
window.frames['iframeName']  // 通过器 iframe 的 name 属性。

值得说明的是,通过数字访问时,其数字并不是对应文档中 iframe 的位置顺序,而应该是按照其生成 DOM 节点的时间顺序。例如,文档加载完成后,通过 JavaScript 的方式生成了一个 iframe 并注册成了 body 的第一个子节点,那么它对应 window 对象并不是 window.frames[0] , 而是 window.frames[window.frames.length - 1]

contentWindow 属性

通过 iframe 元素的 contentWindow 属性同样能够引用其 window 对象。

var iframe = document.getElementsByTagName('iframe')[0];
iframe.contentWindow;

子窗口引用父窗口

parent 属性
window.frames[0].parent === window;  // true

最顶层的 window 对象的 parent 属性就是自身。

window.parent === window; // true,如果该 window 对象处于最顶层
top 属性

top 属性可以直接访问到最外层的 window 对象。如果存在如下的 iframe 嵌套:

window.frames[0].frames[0].frames[0].top === window;// true

安全限制

安全限制才是 iframe 之间相互应用的重点。安全限制并不会限制 window 对象之间的相互访问,但是如果要访问引用 window 对象的属性(或方法)时,处于安全策略,会限制两个页面必须是同域名(端口可以不同)。

如果两个页不在同一个域名下,那么:

var w = window.frames[0]; // OK
 w.someMethod(); // 抛出一个错误

必须是同域名,意味着即使一个是另外一个子域也是不可以的。于是,这就造成了很大的局限性,因为我们经常嵌入来自其他子域的页面。这种情况下,我们可以通过设置文档的 domain 来实现。如果两个子域名分别是,a.example.com 和 b.example.com。那么我们只需要将两个页面的 domain 都设置为 example.com 就可以了。具体如下:

document.domain = 'example.com';

值得一提的是,document.domain 只能设置为当前域的父级域名或者祖先级,而且操作不可逆。如果网页的域名是 a.example.com,那么:

document.domain = 'c.a.example.com';   // 无效
document.domain = 'x.y.com'; // 无效
document.domain = 'example.com'; // 有效
document.domain = 'a.example.com'; // 无效,因为已经被设置为 'example.com'

你可能感兴趣的:(浅析iframe)