探索 Broadcast Channel API 用于跨标签页通信
Broadcast Channel API 实现了不同浏览器窗口、标签页、iframe 和 Web Worker 之间的通信。它为浏览器中多个 上下文 之间的数据和行为同步提供了一种简单高效的方式,从而构建更具响应性和吸引力的 Web 应用程序。
在本文中,我们将探讨 Broadcast Channel API 的概念、用法和实际应用。我们还将通过一个实际示例,构建一个小型应用程序,演示如何使用该 API 向不同的标签页和窗口发送消息。
理解 Broadcast Channel API
Broadcast Channel API 引入了一种机制,允许同一用户和同一浏览器的、同一来源(origin)下的不同上下文之间进行通信。它基于创建单个共享通道的原理,多个浏览器上下文可以随时加入和离开该通道。
加入后,这些上下文可以通过通道发送和接收消息,从而实现无缝的数据交换和事件传播。这种机制消除了对复杂服务器端通信的需求。以下是使用该 API 的简要说明。
创建或加入频道
const bc = new BroadcastChannel("test_channel");
发送消息
bc.postMessage("This is a test message");
接收消息(有关详细信息,请参阅 BroadcastChannel: message event)
bc.onmessage = (event) => {
console.log(event.data);
// { method: "add", note: "This is a test message" }
};
构建 Node.js 应用程序
首先,请按照我们上一篇文章中“在 Vultr 上部署服务器”部分中的步骤部署一个服务器。接下来,通过 SSH 访问服务器终端,并为我们的 Web 应用程序设置一个项目。
我们将使用 Nano 文本编辑器在服务器上创建和编辑项目文件。您可以在 快捷键备忘单 中查找 Nano 的使用帮助。我们还将使用 Uncomplicated Firewall (UFW) 来控制允许进出服务器的流量。在我们的应用程序中,我们使用 Node.js 来提供应用程序的索引,并使用 http-server 运行应用程序。任何其他类型的服务器,如 Python 和 Apache,也可以达到相同的目的。我们还使用端口 8080,通过 UFW 仅允许通过此端口进入流量。
-
创建一个项目目录,并进入该目录。
bashmkdir notes-app cd notes-app -
初始化一个 Node.js 项目。
bashnpm init -y -
安装 HTTP 服务器依赖项。
bashnpm install http-server -
创建一个 HTML 文件。
bashnano index.html -
将以下代码复制并粘贴到
index.html文件中。html<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Note-taking App</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <h1>Note-taking App</h1> <div id="noteList"></div> <div id="noteForm"> <label for="noteInput">New note</label> <input type="text" id="noteInput" placeholder="A note..." /> <button id="addNoteButton">Add Note</button> <button id="resetNoteButton">Reset Notes</button> </div> <script src="app.js"></script> </body> </html> -
保存并退出文件。
-
创建一个 CSS 文件。
bashnano styles.css -
将以下代码复制并粘贴到
styles.css文件中。cssbody { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 20px; } h1 { color: #333; text-align: center; } #noteList { display: grid; row-gap: 10px; background-color: #fff; border: 1px solid #ddd; border-radius: 5px; padding: 10px; margin-bottom: 20px; } #noteList div { background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 3px; padding: 10px; } #noteForm { display: grid; column-gap: 10px; align-items: center; grid-template-columns: max-content 1fr max-content max-content; } #noteInput { padding: 10px; border: 1px solid #ddd; border-radius: 3px; font-size: 16px; } button { padding: 10px 20px; background-color: #4caf50; color: #fff; border: none; border-radius: 3px; font-size: 16px; cursor: pointer; } button:hover { background-color: #45a049; } -
保存并退出文件。
实现 Broadcast Channel API
-
在
notes-app目录中,创建一个 JavaScript 文件。bashnano app.js -
将以下 JavaScript 代码复制并粘贴到
app.js中。jsconst noteList = document.getElementById("noteList"); const noteInput = document.getElementById("noteInput"); const addNoteButton = document.getElementById("addNoteButton"); const resetNoteButton = document.getElementById("resetNoteButton"); let notes = []; function renderNotes() { noteList.innerHTML = ""; notes.forEach((note) => { const noteItem = document.createElement("div"); noteItem.textContent = note; noteList.appendChild(noteItem); }); } addNoteButton.addEventListener("click", () => { const newNote = noteInput.value.trim(); if (newNote) { notes.push(newNote); renderNotes(); noteInput.value = ""; channel.postMessage({ action: "add", note: newNote }); } }); resetNoteButton.addEventListener("click", () => { notes = []; renderNotes(); channel.postMessage({ action: "reset" }); }); const channel = new BroadcastChannel("notes-channel"); channel.addEventListener("message", (event) => { const { action, note } = event.data; if (action === "add") { notes.push(note); renderNotes(); } else if (action === "reset") { notes = []; renderNotes(); } }); -
保存并退出文件。
-
允许端口
8080的传入连接bashsudo ufw allow 8080 -
启动文件服务器。
bashnpx http-server -
访问应用程序 URL
http://<server-ip>:8080
现在您可以并排打开两个浏览器窗口或标签页。在一个页面上添加一个笔记,您会发现该笔记出现在第二个标签页中,而无需刷新页面。尝试重置所有笔记,您会发现笔记从两个标签页中都被删除了,而无需刷新。
让我们看一下我们在 app.js 中编写的代码。renderNotes 函数为每个添加的笔记创建一个元素。addNoteButton 函数允许我们在应用程序中添加笔记,channel.postMessage 将“add”操作广播到其他窗口或标签页。同样,resetNoteButton 允许我们删除所有现有笔记,channel.postMessage 将“reset action”广播到其他窗口或标签页。
最后,创建一个名为 'notes-channel' 的新 BroadcastChannel,允许同一来源下不同窗口/标签页之间进行通信。BroadcastChannel 的事件监听器监听来自频道的 message 事件,并根据提供的信息采取相应的操作。
实际用例和示例
- 在新闻和媒体网站中
- 用例:跨多个窗口同步文章的阅读进度。
- 示例:用户可以在一个窗口中开始阅读文章,并在另一个窗口或标签页中从同一点无缝继续阅读,从而实现一致的阅读体验。
- 在生产力应用中
- 用例:在多个上下文之间实现文档或文件的更改的实时同步。
- 示例:在协作文本编辑器中,一个用户所做的更改可以实时广播到其他上下文。
- 在社交媒体平台上
- 用例:跨多个标签页或窗口通知用户新更新、消息或通知。
- 示例:如果用户为社交媒体平台打开了多个标签页,他们可以在所有上下文中接收实时更新,确保他们不会错过重要信息。
总结
在本文中,我们探讨了 Broadcast Channel API 的概念、用法和实际实现。我们构建了一个基本的同步笔记应用程序,并学习了如何使用 Broadcast Channel API 来构建互联的 Web 体验。
这是一篇 Vultr 的赞助文章。Vultr 是全球最大的私营云计算平台。Vultr 深受开发者喜爱,已为 185 个国家的 150 万多客户提供服务,提供灵活、可伸缩的全球云计算、云 GPU、裸金属和云存储解决方案。了解更多关于 Vultr 的信息。