0
点赞
收藏
分享

微信扫一扫

浏览器窗口间通信

浏览器窗口间通信

浏览器多个标签页窗口间通信,主要是指的同源的多个页面间的通信,主要方法有本地存储通信、​​Web Worker​​​通信、​​Web Socket​​通信。

本地存储通信

通过浏览器对于同源页面本地存储是共享的策略实现通信,主要可以使用​​localStorage​​​、​​cookie​​​、​​indexDB​​​,注意对于​​sessionStroage​​​是在同一会话有效的,在​​MDN​​​中提到,通过点击链接或者使用​​window.open​​​打开的新标签页之间是属于同一个​​session​​​的,新的标签页会继承上一级会话的​​sessionStroage​​​,但新开一个标签页总是会初始化一个新的​​session​​​,即使是同源的,它们也不属于同一个​​session​​。

localStorage

// 页面A
localStorage.setItem('msg', Math.random());

// 页面B
window.addEventListener("storage", function (e) {
console.log(e);
})
// onstorage事件
// 非当前页面对localStorage进行修改时才会触发,当前页面修改localStorage不会触发监听函数
// 在对原有的数据的值进行修改时才会触发监听函数,当新设值与原有值相同时不会触发。

cookie

// 页面A
document.cookie = "msg=1;path=/";

// 页面B
function getCookie(key){
var cookies = {};
document.cookie.replace(/\s*/g,"").split(";").forEach((v) => {
let unit = v.split("=");
cookies[unit[0]] = unit[1];
})
return cookies[key];
}
setInterval(() => {
console.log(getCookie("msg"));
}, 1000);

IndexedDB

// 页面A
var db = null;
var request = indexedDB.open("message");
request.onsuccess = (e) => db = e.target.result;
request.onupgradeneeded = function(event) {
db = event.target.result;
if (!db.objectStoreNames.contains('message')) {
db.createObjectStore('message', { keyPath: 'key' });
}
};

function setData(data){
var transaction = db.transaction(['message'], 'readwrite');
var store = transaction.objectStore(['message']);
var requestData = store.put({ key: "msg", info: data});
requestData.onsuccess = function(e) {
console.log(e.target.result);
};
};

setTimeout(() => setData(1),1000);

// 页面B
var db = null;
var request = indexedDB.open("message");
request.onsuccess = (e) => db = e.target.result;
function readMsg(){
var transaction = db.transaction(['message']);
var objectStore = transaction.objectStore('message');
var requestResult = objectStore.get('msg');

requestResult.onsuccess = function(event) {
console.log(requestResult.result.info);
};
}

setTimeout(readMsg, 3000);

Web Worker

​HTML5​​​中的​​Web Worker​​​可以分为两种不同线程类型,一个是专用线程​​Dedicated Worker​​​,一个是共享线程​​Shared Worker​​​。
​​​Dedicated Worker​​​直接使用​​new Worker()​​​即可创建,这种​​webworker​​​是当前页面专有的。
​​​SharedWorker​​​可以被多个​​window​​​、标签页、​​iframe​​共同使用,但必须保证这些标签页都是同源的。

// 页面A
var worker = new SharedWorker('worker.js');
worker.port.start();
worker.port.postMessage(1);

// 页面B
var worker = new SharedWorker('worker.js');
worker.port.start();
worker.port.onmessage = function(event){
console.log(event.data);
};

// worker.js
var portArr = [];
onconnect = function(e) {
var port = e.ports[0];
if(portArr.indexOf(port) === -1) portArr.push(port);
port.onmessage = function(e) {
portArr.forEach( v => {
v.postMessage(e.data);
})
}
}

Web Socket

使用​​Web Socket​​​将服务器作为数据中转站进行数据传输,可以实现浏览器窗口间通信,但是比较耗费服务器资源。​​WebSocket​​​是​​HTML5​​​开始提供的一种在单个​​TCP​​​连接上进行全双工通讯的协议。​​WebSocket​​​ 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 ​​WebSocket API​​​中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。在​​WebSocket API​​中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道,两者之间就直接可以数据互相传送。

  • 握手阶段采用​​HTTP​​​协议,在普通​​HTTP​​​报文中包含了一些附加头信息,其中附加头信息​​Upgrade: WebSocket​​​表明这是一个申请协议升级的​​HTTP​​请求。
  • 建立在​​TCP​​​协议基础之上,和​​HTTP​​协议同属于应用层。
  • 可以发送文本,也可以发送二进制数据。
  • 数据格式比较轻量,性能开销小,通信高效。
  • 没有同源限制,客户端可以与任意服务器通信。
  • 协议头标识符是​​ws​​​,如果加密传输则为​​wss​​。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://github.com/lmk123/blog/issues/66

举报

相关推荐

0 条评论