iframe经过postMessage跨域通讯

首先回顾一下什么是同源策略html

同源策略

  1. 协议(一般为https)
  2. 端口号(443为https的默认值)
  3. 主机 (两个页面的模数 Document.domain设置为相同的值)

提到iframe有不少人嗤之以鼻,iframe的缺点不少,可是在某些特定场景下,也能够发挥不错的做用,首先看一下iframe的缺点:git

iframe缺点以及解决方案

缺点:github

1.iframe会阻塞主页面的Onload事件;算法

2.相同域iframe和主页面共享http链接池,因此若是相同域用多个iframe会阻塞加载跨域

解决方案:浏览器

动态生成iframe,在主页面加载完成后去生产iframe加载,从而避免阻塞的影响
复制代码

3.iframe 对SEO不友好bash

在广告位以及内部系统等适合的场景中使用iframe
复制代码

iframe跨域通讯

postMessage

API简介
otherWindow.postMessage(message, targetOrigin, [transfer]);
复制代码

otherWindow是window对象的引用:dom

  1. window.open/window.opener 使用window.open返回的对象函数

  2. HTMLIFrameElement.contentWindow iframe元素的contentWindow属性post

  3. window.parent 当前窗口的父窗口对象,若是没有返回自身

  4. window.frames 当前窗口的全部直接子窗口

看起来比较复杂,若是想实现主页面和iframe交互,只须要第二项和第三项

targetOrigin

1.*表明能够发送到任意origin

2.https:www.xxx.com:443能够指定特定的origin发送,默认端口号能够省略

使用

以主页面中嵌套一个iframe为案例说明

主页面:

//html
  <iframe src="./iframe.html" id="iframe" frameborder="0" scrolling="no" width="100%"></iframe>
复制代码
//js
//发送message
var iframe = document.getElementById('iframe')
iframe.contentWindow.postMessage(data, '*')
复制代码

子页面:

//js
//监听message事件
window.addEventListener("message", receiveMessageFromIndex, false);//注意ie中事件绑定是attachEvent
//回调函数
function receiveMessageFromIndex(event) {
//传递的data能够从event.data中获取到
}
复制代码
//发送消息给主页面
window.parent.postMessage(data, '*');
//主页面监听方式和子页面同样
复制代码

这样就比较简单的实现了主页面和子页面的双向通讯。

兼容性

须要注意的是postMessage API中的message在ie8/ie9等一些低版本浏览器中,中是不支持除String之外的其余类型时(由于不支持结构化克隆算法),因此,若是要兼容低版本ie,须要经过JSON.strigify以及JSON.parse去发送和接受。

这里给了一个主页面以及子页面的双向通讯的demo:

演示地址

仓库地址

相关文章
相关标签/搜索