iframe隔离,数据同步问题

背景

A系统两个页面分别用iframe嵌入到B系统,发现A的两个页面没有关联了,数据不共享了。

原因

在将两个页面通过 iframe 嵌入到另一个系统中时,每个页面都是独立的文档,它们在浏览器中是作为独立的对象加载和渲染的。这意味着每个页面都有自己的 JavaScript 上下文和全局变量,它们互相之间不共享这些信息。

当你在一个页面中设置公共参数时,这些参数仅在该页面的 JavaScript 上下文中存在,并不能直接在另一个页面中访问。这是因为每个页面都有自己的全局对象,它们之间的变量和状态是相互隔离的。

解决方法

现在需求就是两个页面都要嵌入,并且数据还要及时同步。

1、A、B系统不同源,postMessage传参

将B系统作为中转父页面,A系统的ifram1页面发送postMessage至父页面,再由父页面发送到A系统的iframe2页面,如下图。

示例代码如下:

iframe1页面发起更新数据

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Frame 1</title>
</head>
<body>
    <h2>Frame 1</h2>
    <button onclick="sendMessage()">Send Message to Frame 2</button>

    <script>
        function sendMessage() {
            // 发送消息到父文档
            window.parent.postMessage('Hello from Frame 1!', 'http://example.com');
        }
    </script>
</body>
</html>

父页面接收并转发至iframe2页面

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Parent</title>
</head>
<body>
    <h1>Parent Page</h1>
    <iframe id="frame1" src="Frame1.html" width="300" height="200"></iframe>
    <iframe id="frame2" src="Frame2.html" width="300" height="200"></iframe>

    <script>
        // 监听来自 Frame1.html 的消息
        window.addEventListener('message', function(event) {
            // 检查消息来源
            if (event.origin !== 'http://example.com') return;

            // 更新 Frame2.html 中的参数
            var frame2 = document.getElementById('frame2');
            frame2.contentWindow.postMessage(event.data, 'http://example.com');
        });
    </script>
</body>
</html>

iframe2页面接收更新

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Frame 2</title>
</head>
<body>
    <h2>Frame 2</h2>
    <div id="message"></div>

    <script>
        // 监听来自父文档的消息
        window.addEventListener('message', function(event) {
            // 检查消息来源
            if (event.origin !== 'http://example.com') return;

            // 显示消息
            document.getElementById('message').textContent = event.data;
        });
    </script>
</body>
</html>

本来在A系统一个公共变量解决的事儿,嵌入进去后却要绕这么一圈才能拿到数据,未免有点太繁琐了。 后面也是将iframe2的内容直接搬到了B系统里面,只用接收显示就行了,实在不行就用上面这种方法吧。

2、A、B系统同源情况下

示例代码

ifram1页面发送

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Frame 1</title>
</head>
<body>
    <h2>Frame 1</h2>
    <button onclick="sendDataToFrame2()">Send Data to Frame 2</button>

    <script>
        function sendDataToFrame2() {
            var dataToSend = "Data from Frame 1";
            window.parent.sendDataFromFrame1ToFrame2(dataToSend);
        }

        // 接收来自 Frame2.html 的数据
        function receiveDataFromFrame2(data) {
            console.log("Received data from Frame 2:", data);
        }
    </script>
</body>
</html>

父页面

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Parent</title>
</head>
<body>
    <h1>Parent Page</h1>
    <iframe id="frame1" src="Frame1.html" width="300" height="200"></iframe>
    <iframe id="frame2" src="Frame2.html" width="300" height="200"></iframe>

    <script>
        // 在父级文档中定义函数,用于从一个子级文档发送数据到另一个子级文档
        function sendDataFromFrame1ToFrame2(data) {
            var frame2 = document.getElementById('frame2').contentWindow;
            frame2.receiveDataFromFrame1(data);
        }

        function sendDataFromFrame2ToFrame1(data) {
            var frame1 = document.getElementById('frame1').contentWindow;
            frame1.receiveDataFromFrame2(data);
        }
    </script>
</body>
</html>

iframe2页面

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Frame 2</title>
</head>
<body>
    <h2>Frame 2</h2>
    <button onclick="sendDataToFrame1()">Send Data to Frame 1</button>

    <script>
        function sendDataToFrame1() {
            var dataToSend = "Data from Frame 2";
            window.parent.sendDataFromFrame2ToFrame1(dataToSend);
        }

        // 接收来自 Frame1.html 的数据
        function receiveDataFromFrame1(data) {
            console.log("Received data from Frame 1:", data);
        }
    </script>
</body>
</html>

可以看到子页面是直接用window.parent调用父页面的方法,然后将发送的值当参数再传到另一个子页面的方法里,就可以获取到变化后的数据了。

两种方案都是基于中转页得以通信,还考虑过数据少的情况下使用sessionStorage,一个页面存,一个页面监听变化,有兴趣的小伙伴可以试试。

相关推荐
prince_zxill41 分钟前
Node.js 和 npm 安装教程
前端·javascript·vue.js·npm·node.js
弄不死的强仔1 小时前
可被electron等调用的Qt截图-录屏工具【源码开放】
前端·javascript·qt·electron·贴图·qt5
霸王蟹2 小时前
el-table组件样式如何二次修改?
前端·javascript·vue.js·笔记·学习·前端框架
十八朵郁金香8 小时前
【VUE案例练习】前端vue2+element-ui,后端nodo+express实现‘‘文件上传/删除‘‘功能
前端·javascript·vue.js
LCG元9 小时前
Vue.js组件开发-实现全屏图片文字缩放切换特效
前端·javascript·vue.js
还是鼠鼠10 小时前
图书管理系统 Axios 源码__新增图书
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
还是鼠鼠13 小时前
图书管理系统 Axios 源码 __删除图书功能
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
轻口味13 小时前
Vue.js `Suspense` 和异步组件加载
前端·javascript·vue.js
还是鼠鼠14 小时前
图书管理系统 Axios 源码__编辑图书
前端·javascript·vscode·ajax·前端框架
北极象15 小时前
vue3中el-input无法获得焦点的问题
前端·javascript·vue.js