likes
comments
collection
share

使用JavaScript实现跨标签页通信,建议收藏备用!

作者站长头像
站长
· 阅读数 18

在 Web 开发中,有时我们需要实现不同页面之间的数据传递和事件触发,比如一个页面打开了另一个页面,然后在新的页面中操作后需要更新原来的页面的内容。这种场景在电商、支付、社交等领域都很常见,那么如何用js来实现不同页面之间的交互呢?本文提供几种常见的方法供大家学习参考!

一、localStorage

通过 localStorage 结合 window.addEventListener('storage', cb) 完成 A、B 标签页间通信。

// A标签页
localStorage.setItem('send-msg', JSON.stringify({
    name: 'hzd',
    age: '18',
}))

// B标签页
window.addEventListener('storage', (data) => {
    try {
        console.log(data)
        const msg = JSON.parse(data.newValue)
    } catch (err) {
        // 处理错误
    }
})

在控制台打印一下 data 的值,可以看到挺多信息:

使用JavaScript实现跨标签页通信,建议收藏备用!

二、BroadcastChannel

Broadcast Channel API 表示一个命名频道,给定来源的任何浏览上下文都可以订阅该频道。它允许同一来源的不同文档(在不同窗口、选项卡、框架或 iframe 中)之间进行通信。

// A页面
const bc = new BroadcastChannel("test_channel");
bc.postMessage("This is a test message.");


// B页面
const bc = new BroadcastChannel("test_channel");
bc.onmessage = (event) => {
  console.log(event);
};

使用JavaScript实现跨标签页通信,建议收藏备用!

三、postMessage

postMessage 是 H5 引入的 API,该方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档、多窗口、跨域消息传递,多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案。

使用JavaScript实现跨标签页通信,建议收藏备用!

下面看两个简单的使用例子:

示例一:

// 发送端:

<button id="btn">发送消息</button>

<script>
  let device = window.open('http://localhost:63342/signal_communication/postMessage/receive.html')

  document.getElementById('btn').addEventListener('click', event => {
    device.postMessage('发送一条消息')
  })
</script>
// 接收端:

<script>
  window.addEventListener('message', event => {
    console.log(event)
  })
</script>

使用JavaScript实现跨标签页通信,建议收藏备用!

示例二:

// 发送端:

<div>
    <input id="text" type="text" value="Runoob" />
    <button id="sendMessage" >发送消息</button>
</div>
<iframe id="receiver" src="https://c.runoob.com/runoobtest/postMessage_receiver.html" width="300" height="360">
    <p>你的浏览器不支持 iframe。</p>
</iframe>
<script>
window.onload = function() {
    let receiver = document.getElementById('receiver').contentWindow;
    let btn = document.getElementById('sendMessage');
    btn.addEventListener('click', function (e) {
        e.preventDefault();
        let val = document.getElementById('text').value;
        receiver.postMessage("Hello "+val+"!", "https://c.runoob.com");
    });
}
</script>
// 接收端:

<div id="recMessage">Hello World!</div>

<script>
window.onload = function() {
    let messageEle = document.getElementById('recMessage');
    window.addEventListener('message', function (e) {  // 监听 message 事件
        alert(e.origin);
        if (e.origin !== "https://www.runoob.com") {  // 验证消息来源地址
            return;
        }
        messageEle.innerHTML = "从"+ e.origin +"收到消息: " + e.data;
    });
}
</script>

四、webSocket

这种方式工作中常用,这里忽略跳过

五、SharedWorker

SharedWorker 是一种特殊的 WebWorker,可有支持多个浏览器上下文的通信功能,例如多个窗口、iframe,如果要使 SharedWorker 连接到多个不同的页面,这些页面必须是同源的(相同的协议、host 以及端口)。

SharedWorker 需要提供一个js静态资源文件,该文件用于让各个页签项目加载

let clients = [];
onconnect = function(e) {
  let port = e.ports[0];
  clients.push(port);
  port.addEventListener("message", function(e) {
    for (let i = 0; i < clients.length; i++) {
      let eElement = clients[i];
      eElement.postMessage(e.data);
    }
  });
  port.start();
};

然后使用 ShareWorker 构造函数加载这个脚本 ,并添加相关事件进行监听

this.shareWorker = new SharedWorker("https://www.xxxx.com/static/lib/worker.js");
// 接受信息
this.shareWorker.port.onmessage = (e)=> { 
  console.log(e.data)
}
// 发送信息
this.shareWorker.port.postMessage({
    type : 'notifyTab',
    payload : {}
});