从跨域和同域两个角度实现多页面之间的通信

时间:2023-01-20 20:14:48

一、同域下页面之间的通信

该条件下实现的方式比较多,先列举几种典型的方法,然后举例说明其中几种。
1、iframe标签可以嵌套另一个标签,并且可以通过js去访问被包含的页面的window对象,从而操作该页面下documentElement;
2、使用H5中的webstorage来实现,利用localeStorage和sessionStorage存储进行数据通信;
3、使用cookie,读取相同域名下的cookie值来进行通信;
4、Window.name通信。(有专门的文章进行讲解)
例子1:有一个源窗口A和一个目标窗口B,B是在A中以超链接的形式打开的,在两个窗口同时存在的场景下,如何保证这两个窗口间的持续性通讯。
其中窗口A:

var message = '';

document.querySelector("#boy").onclick = function() {
message = '我是男生,帅气的男生!';
};
document.querySelector("#girl").onclick = function() {
message = '我是女生,漂亮的女生!';
};
window.addEventListener('message', function(e) {
var interval;
// 检测来源
if (e.origin == 'http://www.zhangxinxu.com')
switch (e.data) {
case 'ready':
// e.source 为发送的 window 对象
interval = setTimeout(function(win) {
win.postMessage(message,'http://www.zhangxinxu.com');
}, 2000, e.source);
break;

case 'closed':
clearInterval(interval);
break;
}
}, false);

窗口B:

window.addEventListener('message', function(e) {
document.querySelector("#message").innerHTML = "接受到的信息是:" + e.data;
}, false);

// 当文档加载完毕, 给父级来源发送信息。
window.addEventListener('load', function(e){
e.currentTarget.opener.postMessage('ready', 'http://www.zhangxinxu.com');
}, false);

// 当窗体关闭,告诉父级窗体已经关闭了。
window.addEventListener('unload', function(e){
e.currentTarget.opener.postMessage('closed', 'http://www.zhangxinxu.com');
}, false);

代码分析:子窗口可以使用window.opener来引用父窗口
例子2:通过iframe打开

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>

window.onload = function() {

var oBtn = document.getElementById('btn');
var oMyIframe = document.getElementById('myframe');

oBtn.onclick = function() {

//如果我们要操作一个iframe里面的dom元素,首先要获取到iframe引入的页面的window
//oMyIframe.contentWindow -> 被iframe包含的页面的window对象
//alert(oMyIframe.contentWindow);

oMyIframe.contentWindow.document.body.style.background = 'red';

}

}
</script>
</head>

<body>
<input type="button" value="点击我,改变2.iframe.html的背景色" id="btn" />
<iframe id="myframe" src="2.iframe.html"></iframe>
</body>
</html>

代码分析:一个页面可以通过iframe来嵌套另外一个页面,被包含的页面又可以继续通过iframe标签也继续嵌套其他页面,这样就是一种层级关系。
我们知道window指的是当前页面窗口,那么parent指的是父级窗口,top指的是*窗口,三者可能会表示相同窗口。

二、跨域下页面之间的通信

1、利用iframe和location.hash,数据直接暴露在了url中,数据容量和类型都有限;
2、HTML5中最炫酷的API之一:就是 跨文档消息传输Cross Document Messaging。高级浏览器Internet Explorer 8+, chrome,Firefox , Opera 和 Safari 都将支持这个功能。这个功能实现也非常简单主要包括接受信息的”message”事件和发送消息的”postMessage”方法;
3、Window.name通信。(有专门的文章进行讲解)
例如:
发送消息的”postMessage”方法
向外界窗口发送消息:

otherWindow.postMessage(message, targetOrigin);

代码分析:
otherWindow: 指目标窗口,也就是给哪个window发消息,是 window.frames 属性的成员或者由 window.open 方法创建的窗口。
参数说明:
message: 是要发送的消息,类型为 String、Object (IE8、9 不支持)
targetOrigin: 是限定消息接收范围,不限制请使用 ‘*’。
接受信息的”message”事件:

var onmessage = function (event) {
var data = event.data;
var origin = event.origin;
//do someing
};
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', onmessage, false);
} else if (typeof window.attachEvent != 'undefined') {
//for ie
window.attachEvent('onmessage', onmessage);
}

代码分析:
回调函数第一个参数接收 Event 对象,有三个常用属性:
data: 消息
origin: 消息来源地址
source: 源 DOMWindow 对象