vue中iframe子页面和父页面之间相互通信

在Vue项目中,iframe子页面与父页面通信通常遇到挑战。本文介绍了使用`postMessage`方法进行通信的解决方案。首先,由于window.parent.vm无法在纯HTML子页面中获取,作者放弃了此方法。接着尝试通过getElementById,但不被青睐。最终,作者详细阐述了`postMessage`的使用,指出需将消息发送给`window.parent`,并监听`message`事件以执行相应方法,实现了跨域通信。

vue中iframe子页面和父页面之间相互通信

问题

在实际的开发中遇到一个需求,就是iframe子页面需要调用父页面的方法,起初百度使用了window.parent.vm*来调用父页面的方法,后来发现在iframe的纯html页面中根本取不到vm,遂推测应该是两个vue工程页面之间的调用可以用这个;接着又使用了window.parent.getElementId(‘xxx’),这种方法理论上来说应该是可行的,但是我懒且不喜欢这种调用方式,就没有深究,放弃了这种方法的尝试。所以找到了postMessage这种方法,感觉还不错,就选择了这个。

解决方法

postMessage的使用还是很简单的,也能够实现跨域间的通信,感觉很好用,下面就是使用方法:
发送端

window.parent.postMessage(data, '*');

“*”代表所有的地址都能接收到信息,这个地方其实是目标路径,可以根据自己的实际路径进行更改;这里有一块需要注意的地方,在第一次使用的时候,我使用了window.postMessage,但不知道什么原因,接收不到信息,改为window.parent.postMessage之后就可以了;
接收端:

window.addEventListener('message', (ev) => {
        var data = ev.data;
	        //下面可以调用我们html页面js中的方法,使用传递的数据进 行操作了
	        console.log(data);
	}, false);

接收端比较明朗了,就是监听message字段,消息发送成功后触发此事件,进而进行具体方法的执行。

<think>我们正在讨论页面父页面的区别。根据之前的引用,我们知道页面通常是通过iframe嵌入在父页面中的页面,而父页面则是包含iframe的容器页面。它们的区别主要体现在以下几个方面: ### 1. **层级关系** - **父页面**:作为容器,包含一个或多个`<iframe>`元素,用于嵌入其他页面页面)。 - **页面**:通过`<iframe>`标签被嵌入到父页面中,是父页面的直接下级。 ### 2. **DOM访问权限** - **页面访问父页面**:页面可以通过`window.parent`访问父页面的DOMJavaScript对象[^1][^3]。例如: ```javascript // 在页面中获取父页面的元素值 var parentValue = window.parent.document.getElementById("parentElement").value; ``` - **父页面访问页面**:父页面可以通过`iframe`元素的`contentDocument`属性获取页面的DOM[^1]。例如: ```javascript // 在父页面中获取页面的元素值 var iframe = document.getElementById("childFrame"); var childValue = iframe.contentDocument.getElementById("childElement").value; ``` ### 3. **作用域与安全性** - **独立作用域**:父页面页面拥有各自独立的JavaScript执行环境DOM树,不能直接互相访问变量或函数(除非通过`window.parent`或`contentDocument`显式访问)。 - **同源策略限制**:如果父页面页面不同源(协议、域名、端口任一不同),则互相访问DOM会受到浏览器同源策略的阻止[^1][^2]。此时需要使用`window.postMessage`进行安全的跨域通信。 ### 4. **典型应用场景** - **父页面**:作为布局容器,通常包含导航栏、侧边栏等公共组件,并管理页面的加载切换(如单页应用)。 - **页面**:承载独立功能模块(如地图、表格、图表等),通过嵌入方式与父页面协同工作[^2]。例如: > 页面需要触发父页面的导航更新时,可调用`window.parent.updateNavigation()`[^2]。 ### 5. **通信机制** - **同源场景**:直接通过`window.parent`或`contentDocument`访问。 - **跨域场景**:使用`postMessage` API安全传递数据(见下方示例)[^1]。 ```javascript // 父页面页面发送消息 document.getElementById("childFrame").contentWindow.postMessage("Hello child!", "https://child-domain.com"); // 页面接收消息 window.addEventListener("message", (event) => { if (event.origin !== "https://parent-domain.com") return; console.log("Received from parent:", event.data); }); ``` ### 总结对比表 | **特性** | **父页面** | **页面** | |------------------|-------------------------------|-------------------------------| | **定义** | 包含`<iframe>`的容器页面 | 被嵌入`<iframe>`中的页面 | | **访问对方DOM** | 通过`iframe.contentDocument` | 通过`window.parent.document` | | **独立性** | 可独立运行 | 通常依赖父页面环境 | | **典型用途** | 整体布局、公共组件 | 模块化功能实现 | > **注意**:实际开发中应优先考虑组件化(如React/Vue组件)替代`iframe`,以避免性能安全问题。`iframe`适用于第三方内容嵌入(如广告、地图)或隔离沙箱环境[^4]。 --- §§相关问题§§ 1. 如何使用`postMessage`实现安全的跨域父页面通信? 2. 在哪些场景下应该避免使用`iframe`? 3. 如何检测当前页面是否被嵌套在`iframe`中? 4. 现代前端框架(如React)有哪些替代`iframe`的组件封装方案? [^1]: 页面访问父页面。当页面是嵌套在父页面的 `<iframe>` 中时,页面可以通过 window.parent 访问父页面的 DOM JavaScript。这种方式适用于父页面在同一域下的情况。 [^2]: 为什么需要用到这个功能,是为了实现跨页面交互与通信,因为有一些功能是需要跨页面使用父页面的函数来达到想要的效果。 [^3]: 使用`window.parent`对象刷新父页面。 [^4]: html关闭页面刷新父页面,js关闭模态窗口刷新父页面或跳转页面。 </think>### 页面父页面的区别详解 #### 一、结构关系 1. **嵌套关系** - **父页面**:包含`<iframe>`标签的主页面,是整个应用的容器 示例:`<iframe src="child.html"></iframe>` [^2] - **页面**:通过`<iframe>`嵌入的独立HTML文档 示例:`child.html`中的内容[^1] - $$ \text{页面层级} : \boxed{\text{父页面}} \supset \boxed{\text{页面}} $$ 2. **独立性** - 页面拥有完整的`window`对象独立DOM树 - 父页面控制页面的尺寸、可见性加载行为[^2] #### 二、作用域与访问权限 | 特性 | 父页面 | 页面 | |------|--------|--------| | 访问对方DOM | 通过`iframe.contentDocument` | 通过`window.parent.document` [^1] | | 调用函数 | `iframe.contentWindow.childFunc()` | `window.parent.parentFunc()` [^2] | | 作用域隔离 | 无法直接访问页面变量 | 无法直接访问父页面变量 | | 跨域限制 | 受同源策略约束 | 受同源策略约束 [^3] | #### 三、典型应用场景 1. **父页面作用** - 作为应用框架(导航栏/侧边栏) - 管理多个功能模块(通过切换不同页面) - 实现全局状态管理(如用户登录信息)[^2] 2. **页面作用** - 封装独立功能模块(如地图、编辑器) - 安全隔离第三方内容(广告/支付) - 实现按需加载提升性能(延迟加载页面)[^4] #### 四、通信机制区别 ```javascript // 父 → 通信 (父页面中) document.getElementById("myFrame").contentWindow.postMessage(data); // → 父通信 (页面中) window.parent.postMessage("update_status", "*"); ``` - **父页面特权**:可直接控制页面的生命周期(加载/卸载) - **页面限制**:需通过`window.top`访问顶级页面(多层嵌套时)[^3] #### 五、安全性与性能 1. **安全边界** - 页面提供沙箱隔离,防止恶意脚本影响父页面 - `sandbox`属性可限制页面权限(如禁止表单提交) 2. **性能影响** - 每个页面是独立渲染进程(增加内存开销) - 跨页面通信组件通信消耗更大资源[^4] > **最佳实践**:现代前端优先考虑组件化(React/Vue组件)替代iframe,仅在需要严格隔离时使用页面方案。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值