获取弹出的窗口_Web开发中的跨窗口通信

跨窗口通信

一个窗口来自 baidu.com,另一个是 163.com,那么我们就不希望 baidu.com 的脚本可以阅读我们的邮件,这是由于“同源策略”限制了窗口之间的互相访问。

什么是同源?

如果两个URL具有相同的协议、相同的域名和端口,我们称它是同源的。例如以下几个示例:

  • http://website.com
  • http://website.com/
  • http://website.com/my/page.html

那么以下就不能称是同源的

  • http://www.website.com (www. 域名与其他不同)
  • http://website.org (.org 域名与其他不同)
  • https://website.com (协议与其他不同: https)
  • http://website.com:8888(端口与其他不同:8888)

特殊情况

同源策略里面有一种特殊情况,如果窗口有相同的二级域名,像这样a.baidu.com和b.baidu.com,我们可以使用Javascript将document.domain设置为相同的二级域名baidu.com。那么此时这些窗体都将视为同源的

document.domain = 'baidu.com';

然后他们就可以无限制进行窗体之间的互动了,仅适用于具有相同二级域名的页面。

iframe

一方面,iframe就是一个标签,从另一方面来看,它是嵌套在窗体中的窗体。

嵌入的窗体有它单的的document和window对象,我们可以这样访问他们:

  • iframe.contentWindow 是对
  • iframe.contentDocument 是对

我们在访问嵌套的窗体时,浏览器时会检查iframe是否同源,如果不同源,会拒绝我们相互访问。举例如下:

f4de5fd036cb1b2a39b48825631b28f7.png

上述代码除了以下操作都会报错:

  1. 通过 iframe.contentWindow 获取内部窗口的 window
  2. 修改它的 location

备注:

iframe.onload 实际上与 iframe.contentWindow.onload 相同,当嵌入窗口内所有资源全部加载完后触发。 但是 iframe.onload 始终是可用的,然而 iframe.contentWindow.onload 需要满足同源策略。

对于同源,想怎么做就怎么做

dafc67e0c05c82174832d3a8fe295169.png

等待iframe加载完成

我们咋子创建iframe的时候,它会立即有一个document,但是这个document与最终页面加载完成的document是不同的,看下面的代码:

7b82d747ec15075e3fa72ba3c9052181.png

对于初学者而言,这应该是一个不易察觉的陷阱。其实我们不能立即就用这个document对象,我们在它上面增加任何事件都会被忽略掉。但是如果我们希望更早的时候就能使用它,在同源情况下可以这样,当然如果你有更好的办法,欢迎在评论区留言告诉我。

1bcd096220c0f425b8e3d7726f94f5b7.png

window.frames

获取

  • 通过索引window.frames[0]
  • 通过名称获取:window.frames.myiframe(获取 name="myiframe" 的 iframe 窗口)

示例:

6cd5cc16ff05ff3ebbcfbb14753e6e10.png

一个 iframe 内如果嵌套了其他的 iframe,相应的 window 对象会也形成嵌套结构,可以通过以下方式获取

  • window.frames(子窗口的集合(用于嵌套的 iframe))。
  • window.parent ( 对"父"(外部)窗口的引用)。
  • window.top(对最顶级父窗口的引用)。

举例

a6c6dfdc82d449b93ad474d673eb4ba0.png

检测top属性,来确定是否时在iframe下打开的

43d2bcbe33ecd6a40a8ccd31106c5cf3.png

sandbox 属性

sandbox属性可以在iframe中禁止一些特定的操作,防止不被信任的代码执行,有关于此属性的应用可以自行了解下,以下时它的一些属性

  • allow-top-navigation

允许 iframe 修改父窗口的地址。

  • allow-forms

允许在 iframe 内提交表单。

  • allow-scripts

允许在 iframe 内运行脚本。

  • allow-popups

允许来自 iframe 的 window.open 弹出窗口

备注:

"sandbox" 属性的目的是为了添加更多限制。它不能移除这些限制,尤其是当 iframe 是非同源时,更不能放松同源策略。

跨窗口通信

通过 postMessage 这个接口,我们可以在不同源的窗口内进行通信

  • postMessage

看代码:

ec8cf918601a4b2d7e915e4dfa1f9529.png

只有当 win 内的站点是 http://example.com这个源时才会接受消息,如果不想有这样的限制,那么我们可以这样

918d3f9ea359dc7a246f620c791a9111.png
  • onmessage

为了接收消息,目标窗口应该在 message 事件上增加一个处理函数。当 postMessage 被调用时这个事件会被触发(并且 targetOrigin 检查成功),举例

33fe3ac9009c1e01a3ef26699e385abb.png

总结一下

本文简单的介绍了下web开发中的跨窗体通信,降到了一些需要注意的地方,如果觉得本文对你有帮助,请麻烦点个关注吧!谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值