北京乐逍遥网站设计有限公司|乐逍遥网站设计|乐逍遥网站建设|乐逍遥建站|php知识|前端技术|后端技术|网站源码|移动开发|网站运营|UI设计|数据库|网站设计|网站开发|小程序|乐逍遥每日一句|乐逍遥福利图片
主页 > 前端开发 > JavaScript >

js在浏览器的两个页面之间通信详解

时间:2021-03-01  编辑:

js在浏览器的两个页面之间通信详解

两个浏览器窗口间通信总结:


1、localStorage

一个窗口更新localStorage,

另一个窗口监听window对象的”storage”事件,来实现通信。


1
2
3
4
5
6
7
8
// 本窗口的设值代码
localStorage.setItem('aaa', (Math.random()*10).toString())
  
// 其他窗口监听storage事件
window.addEventListener("storage", function (e) {
  console.log(e)
  console.log(e.newValue)
})


注:两个页面要同源(URL的协议、域名和端口相同)


2、WebSocket

每个页面开启同一个地址的WebSocket服务,利用send发送消息,利用onmessage获取消息的变化。


1
2
3
4
5
6
7
8
9
var ws = new WebSocket("ws://localhost:3000/")
ws.onopen = function (event) {
  // 或者把此方法注册到其他事件中,即可与其他服务器通信
  ws.send({now : Date.now()}); // 通过服务器中转消息
};
ws.onmessage = function (event) {
  // 消费消息
  console.log(event.data);
}


优点:

不仅能在不同窗口之间,还能跨浏览器,兼容性最佳。

缺点:

需要消耗点服务器资源


3、postMessage

postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。


消息发送:otherWindow.postMessage(message, targetOrigin);


otherWindow

其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

.message

要传递的数据,由于部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数字符串化

targetOrigin

通过窗口的origin属性来指定哪些窗口能接收到消息事件,

参考链接 :https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage


消息接收监听:监听message事件


1
2
3
4
5
6
7
8
9
10
//发送消息页面
<iframe onLoad="loadIFreamSite()"  id="loadIframeSite"   src="地址"  frameborder="0" scrolling="no" allowtransparency=true style="width: 100%;" ></iframe>
function loadIFreamSite(){
  var iframe = document.querySelector('#loadIframeSite');
  iframe.contentWindow.postMessage({a: 1}, '*');
}
//监听消息页面
window.addEventListener('message', function(e) {
     // 监听消息内容
}, true);


4、cookie + setInterval【差】

在页面A设置一个使用 setInterval 定时器不断刷新,检查 Cookies 的值是否发生变化,如果变化就进行刷新的操作。


缺点:相当浪费资源


5、SharedWorker

HTML5 中的 Web Worker 可以分为两种不同线程类型,

一个是专用线程 Dedicated Worker,

一个是共享线程 Shared Worker。


Dedicated Worker直接使用new Worker()即可创建,这种webworker是当前页面专有的。


SharedWorker可以被多个window、标签页、iframe共同使用,但必须保证这些标签页都是同源的

具体实列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// a.html
<input id='number1' />
<input id='number2' />
<div class='result1'></div>
 
var first = document.querySelector('#number1');
var second = document.querySelector('#number2');
 
var result1 = document.querySelector('.result1');
 
if (!!window.SharedWorker) {
  var myWorker = new SharedWorker("b.js");
 
  first.onchange = function() {
    myWorker.port.postMessage([first.value, second.value]);
    console.log('Message posted to worker');
  }
 
  second.onchange = function() {
    myWorker.port.postMessage([first.value, second.value]);
    console.log('Message posted to worker');
  }
 
  myWorker.port.onmessage = function(e) {
    result1.textContent = e.data;
    console.log('Message received from worker');
    console.log(e.lastEventId);
  }
}
 
// b.js
onconnect = function(e) {
  var port = e.ports[0];
  port.onmessage = function(e) {
    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
    port.postMessage(workerResult);
  }
}


6、直接引用

其实本质上就是直接获取对方DOM


1
2
3
4
// 父页面获取子iframe
document.getElementById('iframe的id').contentWindow.document
// 子iframe获取父页面
window.parent.document

缺点

只适用于两个页面在同一域,比如在A页面中嵌套一个同源的iframe

返回
顶部