先来一个官方文档: https://developer.mozilla.org/en-US/docs/web/html/Element/iframe
iframe 在 Web 应用刀耕火种的开发年代是非常常见的, 现在基于 Node 构建的前端应用嵌入 iframe 的场景越来越少了, 但是在大型的 Web 应用中也会经常遇见利用 iframe 嵌入多个前端应用于一套前端系统中, 方便用户在一个系统中去进行业务操作, 而不需要在几个不同的系统中来回切换, 好了应用场景说了这么多, 正式开始吧.
iframe 可以理解为一个 DOM 里面插入了一个窗口级应用, iframe 有自己独立的 Windows,iframe 窗口自己内部的逻辑操作可以独立, 当然在同域条件下, iframe 窗口可以访问父级窗口, 父级窗口也可以访问 iframe 窗口, 跨域情况下只能通过 Windows.postMessage() 通信的方式告诉对方自己想要的操作.
使用 iframe 只要能拿到父级给的参数, iframe 内部就可以进行一系列操作, 登录, 鉴权等. 那怎么获取到父级的参数就需要思考了.
大致以下几种:
1. 通过 iframe 的 URL 参数携带参数信息.
此方法比较简单方便, 也是比较常见的方法, 主系统也不用做额外的开发, 只需要在访问的时候, 动态切换 URL 路径就行, 此方法不管同域跨域都可以使用.
2. 同域情况下, 父子级直接相互操作即可, 调用相应的方法即可.
调用函数:
父级页面调用子页面的函数 name.Windows.func(),name 为 iframe 的 name
子页面调用父级页面的函数
- parent.Windows.func()
- ;
访问页面元素
- name.Windows
- parent.Windows
Windows 都能拿到, dom,localstorage,session 等还拿不到吗?
注意
保证 iframe 已经加载成功
3. 跨域情况下就用 Windows.postMessage(), 此方法一样要保证 iframe 加载成功
直接给个例子
父窗口发消息
- setIframe(){
- let data = 'test' // data 尽量字符串, 存在兼容性问题, 若要传对象, 将对象转化为字符串再传递
- let hcfIframe:any = document.getElementById('hcfIframe')
- // iframe 加载需要时间, 递归发送消息
- if(hcfIframe){
- // contentWindow 属性返回 < iframe > 元素的 Windows 对象. 你可以使用这个 Windows 对象来访问 iframe 的文档及其内部 DOM.contentWindow 为只读, 但是可以像操作全局 Windows 对象一样操作其属性.
- hcfIframe.contentWindow.postMessage(data,'http://localhost:8001/#/');
- return
- }else{
- setTimeout(() => {
- this.setIframe()
- },200)
- }
- }
iframe 窗口接收消息
- // 回调函数
- function receiveMessageFromIframePage (event) {
- console.log('receiveMessageFromIframePage', event)
- }
- // 监听 message 事件
- Windows.addEventListener("message", receiveMessageFromIframePage, false);
接收消息后你就可以进行相应的操作了.
来源: http://www.jianshu.com/p/24157aff6b54