跨标签页通信(四):SharedWorker

跨标签页通信(四):SharedWorker

在现代 Web 开发中,跨标签页通信的需求越来越普遍。无论是实现多标签页之间的数据同步,还是构建实时协作功能,跨标签页通信都能极大地提升用户体验。今天,我们将探讨一种高效且易于实现的方案:SharedWorker

一、什么是 SharedWorker?

SharedWorker 是一种可以在多个浏览器上下文(如多个窗口、iframe 或其他 worker)之间共享的特定类型的 worker。它与普通的 worker 不同,具有独立的全局作用域,并且可以跨多个页面共享数据。如果要使 SharedWorker 连接到多个不同的页面,这些页面必须是同源的(即协议、主机和端口相同)。

(一)特点

  • 跨上下文共享:可以在多个浏览器上下文之间共享数据。
  • 独立作用域 :每个 SharedWorker 都有自己的全局作用域,与其他页面或 worker 隔离。
  • 事件驱动 :通过 postMessage 方法发送消息,并通过监听 message 事件接收消息。

(二)适用场景

  • 多标签页数据同步:在多个标签页之间共享数据,如用户状态、实时消息等。
  • 实时协作:多个用户在不同标签页上协作编辑文档或进行实时交互。
  • 性能优化:减少重复的网络请求,通过共享数据提升性能。

二、SharedWorker 实现跨标签页通信

(一)创建 SharedWorker

在页面中创建一个 SharedWorker 实例,并通过 port 属性与 worker 进行通信。

页面一:发送消息
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>页面一</title>
</head>
<body>
    <input type="text" id="content" placeholder="请输入消息">
    <button id="btn">发送消息</button>
    <script>
        const content = document.querySelector('#content');
        const btn = document.querySelector('#btn');

        // 创建一个 SharedWorker
        const worker = new SharedWorker('worker.js');

        btn.onclick = function () {
            worker.port.postMessage(content.value);
        };
    </script>
</body>
</html>
页面二:接收消息
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>页面二</title>
</head>
<body>
    <script>
        const worker = new SharedWorker('worker.js');
        worker.port.start();

        worker.port.onmessage = function (e) {
            if (e.data) {
                console.log(`来自 worker 的数据:`, e.data);
            }
        };

        setInterval(function () {
            worker.port.postMessage("get");
        }, 1000);
    </script>
</body>
</html>

(二)SharedWorker 脚本

SharedWorker 脚本中,通过监听 connect 事件来接收页面的连接请求,并通过 port 属性与页面进行通信。

javascript 复制代码
// worker.js
var data = ""; // 存储用户发送过来的信息

onconnect = function (e) {
    var port = e.ports[0];

    port.onmessage = function (e) {
        // 说明要将接收到数据返回给客户端
        if (e.data === "get") {
            port.postMessage(data);
            data = "";
        } else {
            data = e.data;
        }
    };
};

(三)效果

  1. 打开两个标签页,分别加载页面一和页面二。
  2. 在页面一中输入消息并点击"发送消息"按钮。
  3. 页面二的控制台会立即打印出接收到的消息。

三、注意事项

(一)同源限制

SharedWorker 只能在同源页面之间使用。如果页面的协议、域名或端口不同,通信将无法进行。

(二)浏览器支持

虽然现代浏览器(如 Chrome、Firefox、Safari)都支持 SharedWorker,但在使用前最好进行兼容性检查。

javascript 复制代码
if (!window.SharedWorker) {
    console.warn("SharedWorker 不被支持");
}

(三)性能影响

虽然 SharedWorker 的性能开销较小,但在高频率发送消息时,仍需注意对性能的影响。

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
晨米酱2 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
彧azz2 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端