1) cookie + setInterval 方式
注: cookie、localStorage、sessionStorage在同源页面间属于共享资源。(同源:如两个页面的协议、IP地址、端口号相同,即为同源页面)
缺点:
① cookie 空间有限,浏览器在每个域名下最多能设置30-50个cookie,容量最多4k左右
② 每次 HTTP 请求会把当前域的所有cookie发送到服务器上,包括只在本地才用到的。浪费网络带宽
③ setInterval的频率设置,过大会影响浏览器性能,过小会影响时效性
优点:每个浏览器都兼容
1
2
3
4
5// send.html send.onclick = function(){ document.cookie = `msg=${msg.value.trim()}` }
1
2
3
4
5
6
7
8
9
10
11
12
13// rec.html function getKey(key){ // 获取cookie中的指定变量值 return JSON.parse(`{"${ document.cookie.replace(/;s+/gi,'", "').replace(/=/gi,'":"') }"}`)[key] } // 每隔1秒获取cookie的内容 setInterval(function(){ msg.innerHTML = getKey('msg') },1000)
完整版代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- send.html --> <input id="msg1" type="text"> <input id="msg2" type="text"> <button id="send">发送</button> <script> send.onclick = function(){ if(msg1.value.trim() !== '' && msg2.value.trim()){ document.cookie = `msg1=${msg1.value.trim()}` document.cookie = `msg2=${msg2.value.trim()}` } } </script> </body> </html>
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<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- rec.html --> <h1>收到消息:<span id="recMsg1"></span></h1> <h1>收到消息:<span id="recMsg2"></span></h1> <script> console.log(document.cookie) function getKey(key){ // 解析cookie为对象 var cookies = JSON.parse(`{"${ document.cookie.replace(/=/g,'":"').replace(/;s+/g,'", "') }"}`) return cookies[key] } setInterval(() => { recMsg1.innerHTML = getKey('msg1') recMsg2.innerHTML = getKey('msg2') }, 500); </script> </body> </html>
2) localStorage 方式
setItem时,会自动触发整个浏览器的storage事件,除当前页面之外,所有打开的标签都会受影响
缺点:
① localStorage属于HTML5新特性,高版本的浏览器才支持localStorage这个属性,且不同浏览器localStorage大小限制不统一
② localStorage只能监听非己页面的数据变化,这一点严重影响使用
优点:解决了cookie容量小和时效性不足的问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- send.html --> <input id="msg1" type="text"> <input id="msg2" type="text"> <button id="send">发送</button> <script> send.onclick = function(){ if(msg1.value.trim() !== '' && msg2.value.trim()){ localStorage.setItem('msg1', msg1.value.trim()) localStorage.setItem('msg2', msg2.value.trim()) } } </script> </body> </html>
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<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- rec.html --> <h1>收到消息:<span id="recMsg1"></span></h1> <h1>收到消息:<span id="recMsg2"></span></h1> <script> // 页面加载时调用函数 load() // 只要任一同源页面修改了localStorage中的值,都会自动触发其他页面中的storage事件 window.addEventListener('storage', function(){ load() }) // window.addEventListener('storage',load) // 不涉及this情况下,可直接这样写 // 函数:获取localStorage中的值 function load(){ recMsg1.innerHTML = localStorage.getItem('msg1') recMsg2.innerHTML = localStorage.getItem('msg2') } </script> </body> </html>
3)WebSocket 方式
缺点:
① 它需要服务端的支持才能完成任务。如果socket数据量比较大的话,会严重消耗服务器的资源
② 必须要在服务端项目中写服务端监听程序才能支持
优点:如果部署了WebSocket服务器,可以实现很多实时的功能。(如阿里旺旺等网页上的即时通信功能)
实现步骤:
① 实现服务端监听程序
1
2npm init
先创建一个node项目,然后引入ws
1
2npm i -s ws
新建js文件,实现功能代码如下:
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// 获得 WebSocketServer 类型 var WebSocketServer = require('ws').Server // 创建 WebSocketServer 对象实例,监听指定端口 var wss = new WebSocketServer({port:5500}) // 创建保存所有已连接到服务器的客户端对象的数组 var clients = [] // 为服务器添加connection事件监听,当有客户端连接到服务端时,立刻将客户端对象保存进数组中 wss.on('connection', function(client){ console.log('一个客户端连接到服务器') if(clients.indexOf(client) === -1){ clients.push(client) console.log(`有${clients.length}个客户端在线`) // 为每个client对象绑定message事件,当某个客户端发来消息时,自动触发 client.on('message', function(msg){ console.log(`收到消息:${msg}`) // 遍历clients数组中每个其他客户端对象,并发送消息给其他客户端 for(var c of clients){ if(c != client){ c.send(msg) } } }) } })
② 实现发送端代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- send.html --> <input type="text" id="msg"> <button id="send">发送</button> <script> // 建立到服务端的WebSocket连接 var ws = new WebSocket('ws://localhost:5500') send.onclick = function(){ // 点击“发送”按钮,向服务端发送信息 if(msg.value.trim() !== ''){ ws.send(msg.value.trim()) } } </script> </body> </html>
③ 实现接收端代码
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<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- rec.html --> <h1>收到消息:<span id="recMsg"></span></h1> <script> // 建立到服务端的WebSocket连接 var ws = new WebSocket('ws://localhost:5500') // 当连接被打开时,注册接收消息的处理函数 ws.onopen = function(event){ console.log(event) // 当有消息发过来时,就将消息放到显示元素上 ws.onmessage = function(event){ recMsg.innerHTML = event.data } } </script> </body> </html>
④ 运行
运行服务端 node server.js --> 打开发送端和接收端文件 --> 发送消息
4) SharedWorker 方式
实现步骤:
① 创建worker.js,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 在所有SharedWorker共享的worker.js中,保存一个data变量,用于存储多个worker共享的数据 let data = '' // 必须提供一个名为onconnect的事件处理函数 // 每当一个页面中new SharedWorker('worker.js')时,就会为新创建的worker绑定onconnect事件处理函数 onconnect = function(e){ // 获得当前连接上来的客户端对象 var client = e.ports[0] // 当当前对象收到消息时 client.onmessage = function(e){ if(e.data === ''){ // 如果消息内容为空,说明该客户端想获取共享数据data client.postMessage(data) // 给当前客户端发送data数据 }else{ // 如果消息内容不为空,说明该客户端想要提供新的消息保存在共享的data中 data = e.data } } }
② 创建发送方.html,代码如下:
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<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- send.html --> <input type="text" id="msg"> <button id="send">发送</button> <script> var worker = new SharedWorker('worker.js') worker.port.start() send.onclick = function(){ if(msg.value.trim() !== ''){ worker.port.postMessage(msg.value.trim()) } } </script> </body> </html>
③ 创建接收方.html,代码如下:
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<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- rec.html --> <h1>收到消息:<span id="recMsg"></span></h1> <script> var worker = new SharedWorker('worker.js') // 3.当worker.js中给当前客户端返回了data,会触发当前客户端的message事件,data的值自动保存进事件对象e的data属性中 worker.port.addEventListener('message',function(e){ recMsg.innerHTML = e.data }) worker.port.start() // 1.接收端反复向共享的worker.js对象中发送空消息,意为想获取data的值 setInterval(() => { worker.port.postMessage('') // 2.只要发送消息,就会触发worker.js中的onmessage(),onmessage判断是空消息,说明客户端想获得data,于是就用postMessage()方法,将data返回给当前客户端 }, 500); </script> </body> </html>
最后
以上就是沉默汽车最近收集整理的关于2020-8:实现浏览器内多个标签页之间通信的4种方式(html5 & JavaScript)的全部内容,更多相关2020-8:实现浏览器内多个标签页之间通信的4种方式(html5内容请搜索靠谱客的其他文章。
发表评论 取消回复