Iframe跨窗口通信原理详解

同源

同源策略会限制 窗口(window) 和 frame 之间的通信,因此首先要知道同源策略。

同源策略目的是保护用户信息免遭信息盗窃:加入小王有两个打开的页面:一个是 shop.com,一个是 email.com。小王不希望 shop.com 的脚本可以读取 mail 的邮件,这时同源策略就起作用了。

如果两个 URL 具有相同的协议,域,和端口,则称它们是同源的。

以下几个URL是同源的:

  • site.com
  • site.com/
  • site.com/a/index.htm…

以下是不同源的:

  • https://site.com
  • http://bbs.site.com
  • site.com:8080
  • http://site.org

同源策略规定:

  • 如果我们有对另一个窗口的引用(window.open || iframe),并且该窗口是同源的,那么我们就具有对该窗口的全部访问权限。见代码:2-1 、2-2
  • 如果不是同源的,我们就不能访问窗口中的内容:变量,文档,任何东西。唯一例外是location:我们可以修改它,使用它进行重定向。但是我们无法读取 location 。因此,我们无法看到用户当前所处的位置,也就不会泄露任何信息。

iframe

iframe 标签承载了一个单独的嵌入的窗口,它有自己的 documentwindow

iframe.contentWindow 来获取 中的 window

iframe.contentDocument 来获取 中的 document , 是 iframe.contentWindow.document 的简写。

当我们访问嵌入的窗口中的东西时,浏览器会检查 iframe 是否具有相同的源。如果不是,则会拒绝访问(对 location 进行写入是一个例外,它是会被允许的)。

代码 2-1 : (在 同源 情况下)

 
 
 
     我是 1.html, 下面嵌套 2.html
     
     
 
 
 
 
     我是 2.html
     
 

iframe.onload vs iframe.contentWindow.onload

iframe.onload 事件(在 我是 2.html

iframe:错误文档陷阱

当一个 iframe 来自同一个源时,我们可能会访问其 document,但是这里有一个陷阱。它与跨源无关,但你一定要知道。在创建 iframe 后,iframe 会立即就拥有了一个文档。但是该文档不同于加载到其中的文档!

因此,如果我们要立即对文档进行操作,就可能出问题,因为那是错误的文档

正确的文档在 iframe.onload 触发时肯定就位了。但是,只有在整个 iframe 和它所有资源都加载完成时,iframe.onload 才会触发。

看一下下面这段代码:

 let oldDoc = iframe.contentDocument;
 iframe.onload = function() {
     let newDoc = iframe.contentDocument;
     // 加载的文档与初始的文档不同!
     alert(oldDoc == newDoc); // false
 };

window.frames

获取 alert(iframe.contentWindow == frames[0]); // true alert(iframe.contentWindow == frames.win); // true

一个 iframe 内可能嵌套了其他的 iframe。相应的 window 对象会形成一个层次结构(hierarchy)。

可以通过以下方式获取:

window.frames —— “子”窗口的集合(用于嵌套的 iframe)。

window.parent —— 对“父”(外部)窗口的引用。

window.top —— 对最顶级父窗口的引用。

例如:

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

我们可以使用 top 属性来检查当前的文档是否是在 iframe 内打开的:

 if (window === window.top) { 
   alert('不是在 iframe 中打开的');
 } else {
   alert('在 iframe 中打开的');
 }

“sandbox” iframe 特性

sandbox 特性(attribute)允许在 我是 2.html

第一次渲染输出:

1.html name=1; old=10 ,

2.html old=10; name=2; year=2020

刷新页面输出:

1.html old=10; year=2020; name=2 ,

2.html old=10; year=2020; name=2

我们可以得出以下结论:

  • iframe 嵌套的 2.html 设置的 cookie 我们可以从 1.html 中获取
  • iframe 中设置的 cookie 会覆盖 1.html cookie 中 Name相同的值( 不同源也是同样的效果 )

以上就是Iframe跨窗口通信原理详解的详细内容,更多关于Iframe跨窗口通信的资料请关注脚本之家其它相关文章!

你可能感兴趣的:(Iframe跨窗口通信原理详解)