Vue跨域iframe场景下实现内部操作父页面添加元素方案咨询
问题根因
两个项目端口不一致,属于跨域场景,浏览器同源策略禁止iframe直接访问父页面的document对象,所有直接操作父页面DOM的行为都会被安全拦截,必须使用postMessage API实现跨文档通信。
解决方案
1. 改造父页面(运行在localhost:8080)的myiframe.js逻辑,新增消息监听
父页面负责接收iframe发来的消息,收到指定消息后自行操作DOM新增元素,修改后的完整myiframe.js代码如下:
ready(function () { initIframe() addMessageListener() }) /** * Auto execute javascript function * @param callbackFunction */ function ready(callbackFunction) { if (document.readyState != 'loading') callbackFunction() else document.addEventListener('DOMContentLoaded', callbackFunction) } /** * Initialize iframe * @return {Promise<void>} */ function initIframe() { // Set url const baseUrl = 'http://localhost:8081' // Create div tag const divContainer = document.createElement('div') divContainer.setAttribute('id', 'container-iframe') // Create iframe tag const iframe = document.createElement('iframe') iframe.setAttribute('src', baseUrl) divContainer.appendChild(iframe) document.body.appendChild(divContainer) } /** * 监听iframe发来的跨域消息 */ function addMessageListener() { window.addEventListener('message', function(e) { // 安全校验:只接收来自可信源的消息,生产环境替换为实际部署域名 if (e.origin !== 'http://localhost:8081') return // 判断是否为新增div的消息 if (e.data?.type === 'ADD_CONTAINER_DIV') { const container = document.getElementById('container-iframe') if (!container) return // 自定义新增div的内容、样式,也可以从e.data里取iframe传递的自定义参数 const newDiv = document.createElement('div') newDiv.innerText = e.data?.content || '默认新增内容' container.appendChild(newDiv) } }) }
2. 改造iframe内部(运行在localhost:8081)的Vue组件逻辑
iframe内部只需要向父页面发送约定格式的消息,不需要直接操作父页面DOM,修改后的组件代码如下:
<template> <button @click="importIframe">Click me</button> </template> <script> export default { name: 'App', methods: { importIframe() { // 向父页面发消息,第二个参数为父页面源,生产环境替换为实际部署域名 window.parent.postMessage({ type: 'ADD_CONTAINER_DIV', content: 'iframe触发新增的div' // 可自定义传递更多参数,比如样式、属性等 }, 'http://localhost:8080') }, } } </script>
注意事项
- 生产环境部署时,需要将两个项目的源替换为实际的域名,不要保留localhost
- 必须做origin校验,避免恶意页面发送伪造消息导致安全问题
内容的提问来源于stack exchange,提问作者Husdady
相关产品推荐
相关产品推荐

