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