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,一个页面存,一个页面监听变化,有兴趣的小伙伴可以试试。

相关推荐
啊~哈3 分钟前
页面弹窗适配问题
前端·javascript·vue.js
用户3273242098712 分钟前
logger2js - JavaScript日志与调试工具库
javascript
安然dn17 分钟前
Interact.js 一个轻量级拖拽库
javascript
FogLetter20 分钟前
从"乱炖"到"法式大餐":Promise如何优雅地管理异步流程
前端·javascript
williamdsy29 分钟前
【Vue PDF】Vue PDF 组件初始不加载 pdfUrl 问题分析与修复
前端·javascript·vue.js·pdf
我不吃饼干1 小时前
我给掘金写了一个给用户加标签的功能
前端·javascript·cursor
步行cgn2 小时前
Vue 事件修饰符详解
前端·javascript·vue.js
vvilkim2 小时前
Flutter 状态管理基础:深入理解 setState 和 InheritedWidget
前端·javascript·flutter
程序员小张丶3 小时前
基于React Native的HarmonyOS 5.0房产与装修应用开发
javascript·react native·react.js·房产·harmonyos5.0
中微子3 小时前
回调函数详解:C++开发者视角下的JavaScript异步艺术
javascript