前端开发攻略---8种方法实现在浏览器中跨页面通信

news/2024/10/16 18:12:23 标签: javascript, 前端, 开发语言

目录

1、BroadCast Channel

2、Service Worker

3、LocalStorage

4、Shared Worker

5、IndexedDB

6、Cookie

7、Window

8、Websocket

总结:


1、BroadCast Channel

1、创建文件sender.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="messageInput" placeholder="输入消息" />
    <button id="sendButton">发送消息</button>

    <script>
      const channel = new BroadcastChannel('my_channel')

      document.getElementById('sendButton').addEventListener('click', () => {
        const message = document.getElementById('messageInput').value
        channel.postMessage({ message })
      })
    </script>
  </body>
</html>

2、创建文件receiver.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messageDiv"></div>

    <script>
      const messageDiv = document.getElementById('messageDiv')
      const channel = new BroadcastChannel('my_channel')

      channel.onmessage = event => {
        messageDiv.innerHTML += `<p>收到消息: ${event.data.message}</p>`
      }
    </script>
  </body>
</html>

 2、Service Worker

1、创建文件sender.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="messageInput" placeholder="输入消息" />
    <button id="sendButton">发送消息</button>

    <script>
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker
          .register('service-worker.js')
          .then(() => {
            console.log('Service Worker 注册成功')
          })
          .catch(error => {
            console.error('Service Worker 注册失败:', error)
          })
      }

      document.getElementById('sendButton').addEventListener('click', () => {
        const message = document.getElementById('messageInput').value
        navigator.serviceWorker.controller.postMessage({ message })
      })
    </script>
  </body>
</html>

2、创建文件receiver.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messageDiv"></div>

    <script>
      const messageDiv = document.getElementById('messageDiv')

      if ('serviceWorker' in navigator) {
        navigator.serviceWorker
          .register('service-worker.js')
          .then(() => {
            console.log('Service Worker 注册成功')
          })
          .catch(error => {
            console.error('Service Worker 注册失败:', error)
          })

        navigator.serviceWorker.onmessage = event => {
          messageDiv.innerHTML += `<p>收到消息: ${event.data.message}</p>`
        }
      }
    </script>
  </body>
</html>

3、创建文件service-worker.js

javascript">self.addEventListener('message', event => {
  const message = event.data.message
  // 将消息转发给所有客户端
  self.clients.matchAll().then(clients => {
    clients.forEach(client => {
      client.postMessage({ message })
    })
  })
})

  3、LocalStorage

1、创建文件sender.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="messageInput" placeholder="输入消息" />
    <button id="sendButton">发送消息</button>

    <script>
      document.getElementById('sendButton').addEventListener('click', () => {
        const message = document.getElementById('messageInput').value
        localStorage.setItem('message', message)
      })
    </script>
  </body>
</html>

2、创建文件receiver.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messageDiv"></div>

    <script>
      const messageDiv = document.getElementById('messageDiv')

      // 处理存储事件
      window.addEventListener('storage', event => {
        if (event.key === 'message') {
          messageDiv.innerHTML += `<p>收到消息: ${event.newValue}</p>`
        }
      })

      // 如果页面加载时有消息,立即显示
      const initialMessage = localStorage.getItem('message')
      if (initialMessage) {
        messageDiv.innerHTML += `<p>收到消息: ${initialMessage}</p>`
      }
    </script>
  </body>
</html>

  4、Shared Worker

1、创建文件sender.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="message" placeholder="输入消息" />
    <button id="send">发送消息</button>

    <script>
      const worker = new SharedWorker('./sharedWorker.js')
      const messageInput = document.getElementById('message')
      const sendButton = document.getElementById('send')

      // 发送消息
      sendButton.onclick = () => {
        const message = messageInput.value
        if (message) {
          worker.port.postMessage(message)
          messageInput.value = ''
        }
      }

      worker.port.start()
    </script>
  </body>
</html>

2、创建文件receiver.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messages"></div>

    <script>
      const worker = new SharedWorker('sharedWorker.js')
      const messagesDiv = document.getElementById('messages')
      // 接收消息
      worker.port.onmessage = event => {
        messagesDiv.innerHTML += `<p>收到消息: ${event.data}</p>`
      }
      worker.port.start()
    </script>
  </body>
</html>

3、创建文件shared-worker.js

javascript">// sharedWorker.js
let connections = []

onconnect = function (e) {
  const port = e.ports[0]
  connections.push(port)

  port.onmessage = function (event) {
    // 广播接收到的消息给所有连接的端口
    connections.forEach(conn => {
      if (conn !== port) {
        conn.postMessage(event.data)
      }
    })
  }

  port.start()
}

 5、IndexedDB

1、创建文件sender.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="message" placeholder="输入消息" />
    <button id="send">发送消息</button>

    <script>
      const dbName = 'messageDB'
      let db

      // 打开数据库
      const request = indexedDB.open(dbName, 1)

      request.onupgradeneeded = event => {
        db = event.target.result
        db.createObjectStore('messages', { keyPath: 'id', autoIncrement: true })
      }

      request.onsuccess = event => {
        db = event.target.result
      }

      // 发送消息
      document.getElementById('send').onclick = () => {
        const message = document.getElementById('message').value
        if (message) {
          const transaction = db.transaction('messages', 'readwrite')
          const store = transaction.objectStore('messages')
          store.add({ content: message })

          document.getElementById('message').value = ''
        }
      }
    </script>
  </body>
</html>

2、创建文件receiver.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messages"></div>

    <script>
      const dbName = 'messageDB'
      let db

      // 打开数据库
      const request = indexedDB.open(dbName, 1)

      request.onupgradeneeded = event => {
        db = event.target.result
        db.createObjectStore('messages', { keyPath: 'id', autoIncrement: true })
      }

      request.onsuccess = event => {
        db = event.target.result
        fetchMessages()
        setInterval(fetchMessages, 2000) // 每2秒检查一次新消息
      }

      // 获取消息
      function fetchMessages() {
        const transaction = db.transaction('messages', 'readonly')
        const store = transaction.objectStore('messages')
        const request = store.getAll()

        request.onsuccess = event => {
          const messages = event.target.result
          const messagesDiv = document.getElementById('messages')
          messagesDiv.innerHTML = '' // 清空之前的消息

          messages.forEach(msg => {
            const messageElement = document.createElement('div')
            messageElement.textContent = `收到消息: ${msg.content}`
            messagesDiv.appendChild(messageElement)
          })
        }
      }
    </script>
  </body>
</html>

 6、Cookie

1、创建文件sender.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="message" placeholder="输入消息" />
    <button id="send">发送消息</button>

    <script>
      // 设置 Cookie
      function setCookie(name, value, days) {
        const d = new Date()
        d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000)
        const expires = 'expires=' + d.toUTCString()
        document.cookie = name + '=' + value + ';' + expires + ';path=/'
      }

      // 发送消息
      document.getElementById('send').onclick = () => {
        const message = document.getElementById('message').value
        if (message) {
          setCookie('message', message, 1) // 存储消息到 Cookie
          document.getElementById('message').value = ''
        }
      }
    </script>
  </body>
</html>

2、创建文件receiver.html

javascript"><!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messages"></div>

    <script>
      // 读取 Cookie
      function getCookie(name) {
        const value = `; ${document.cookie}`
        const parts = value.split(`; ${name}=`)
        if (parts.length === 2) return parts.pop().split(';').shift()
      }

      // 显示消息
      function displayMessage() {
        const message = getCookie('message')
        const messagesDiv = document.getElementById('messages')
        messagesDiv.innerHTML = '' // 清空之前的消息

        if (message) {
          const messageElement = document.createElement('div')
          messageElement.textContent = `接收到: ${message}`
          messagesDiv.appendChild(messageElement)

          // 清除消息,避免重复显示
          document.cookie = 'message=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
        }
      }

      // 每2秒检查一次新消息
      setInterval(displayMessage, 2000)
    </script>
  </body>
</html>

 7、Window

1、创建文件sender.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="message" placeholder="输入消息" />
    <button id="send">发送消息</button>

    <script>
      let receiverWindow

      // 打开接收消息的窗口
      function openReceiver() {
        if (!receiverWindow || receiverWindow.closed) {
          receiverWindow = window.open('receiver.html', 'ReceiverWindow')

          // 在接收窗口加载完成后,设置监听器
          receiverWindow.onload = () => {
            const message = document.getElementById('message').value
            if (message) {
              receiverWindow.postMessage(message, '*') // 发送消息
            }
          }
        } else {
          receiverWindow.focus()
        }
      }

      // 发送消息
      document.getElementById('send').onclick = () => {
        const message = document.getElementById('message').value
        openReceiver() // 确保接收窗口打开

        // 如果窗口已打开且不为空,发送消息
        if (receiverWindow && message) {
          receiverWindow.postMessage(message, '*') // 发送消息
          document.getElementById('message').value = '' // 清空输入框
        }
      }
    </script>
  </body>
</html>

2、创建文件receiver.html

javascript"><!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messages"></div>

    <script>
      // 接收消息
      window.addEventListener('message', event => {
        const messagesDiv = document.getElementById('messages')
        const messageElement = document.createElement('div')
        messageElement.textContent = `接收到: ${event.data}`
        messagesDiv.appendChild(messageElement)
      })
    </script>
  </body>
</html>

 8、Websocket

1、创建文件sender.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发送消息</title>
  </head>
  <body>
    <h1>发送消息</h1>
    <input type="text" id="message" placeholder="输入消息" />
    <button id="send">发送消息</button>

    <script>
      const socket = new WebSocket('ws://localhost:8080')

      // 发送消息
      document.getElementById('send').onclick = () => {
        const message = document.getElementById('message').value
        if (message) {
          socket.send(message) // 发送消息
          document.getElementById('message').value = '' // 清空输入框
        }
      }
    </script>
  </body>
</html>

2、创建文件receiver.html

javascript"><!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>接收消息</title>
  </head>
  <body>
    <h1>接收消息</h1>
    <div id="messages"></div>

    <script>
      const socket = new WebSocket('ws://localhost:8080')

      // 接收消息
      socket.onmessage = event => {
        console.log(event)

        const messagesDiv = document.getElementById('messages')
        const messageElement = document.createElement('div')
        messageElement.textContent = `接收到: ${event.data}`
        messagesDiv.appendChild(messageElement)
      }
    </script>
  </body>
</html>

3、创建文件server.js

javascript">const WebSocket = require('ws')

const wss = new WebSocket.Server({ port: 8080 })

wss.on('connection', ws => {
  console.log('新客户端连接')

  ws.on('message', message => {
    console.log(`收到消息: ${message}`)

    // 广播给所有连接的客户端
    wss.clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(message.toString())
      }
    })
  })

  ws.on('close', () => {
    console.log('客户端断开连接')
  })
})

console.log('WebSocket 服务器正在运行,监听端口 8080')

4、运行服务器:

javascript">npm install ws
node server.js

总结:

1. Broadcast Channel

  • 优点
    • 简单易用,API 直观。
    • 支持多个标签页间的实时通信。
    • 可以发送任意类型的消息(字符串、对象等)。
  • 缺点
    • 数据传递是基于消息的,可能会有延迟。
    • 不适合大量数据传输。
    • 需要支持的浏览器较新,兼容性可能有限。

2. Service Worker

  • 优点
    • 支持离线操作,可以在网络断开时继续工作。
    • 能够拦截网络请求,提供更大的灵活性。
    • 可以用于后台处理和数据缓存。
  • 缺点
    • 配置和实现相对复杂。
    • 不能直接访问 DOM,使用场景有限。
    • 需要注册和管理生命周期。

3. LocalStorage

  • 优点
    • 简单易用,支持持久化存储。
    • 在同一源(origin)下,所有标签页共享相同的数据。
  • 缺点
    • 同步方式,可能会有数据更新延迟。
    • 存储容量有限(通常为 5MB)。
    • 不支持跨源数据共享。

4. Shared Worker

  • 优点
    • 可以被多个标签页和窗口共享,适合复杂应用。
    • 允许更高效的数据共享与通信。
  • 缺点
    • 实现较复杂,需要理解 worker 的生命周期。
    • 需要支持的浏览器较新。
    • 有时会受到同源政策的限制。

5. IndexedDB

  • 优点
    • 支持大规模数据存储(数百 MB 甚至更多)。
    • 结构化数据存储,支持复杂查询。
    • 异步操作,不会阻塞主线程。
  • 缺点
    • API 较复杂,上手难度较高。
    • 需要考虑数据库版本控制和事务处理。
    • 数据可能需要在不同标签页间进行同步。

6. Cookie

  • 优点
    • 兼容性好,几乎所有浏览器都支持。
    • 可以设置过期时间,适合需要持久化的简单数据。
  • 缺点
    • 数据容量有限(通常为 4KB)。
    • 频繁的网络请求可能导致性能问题。
    • 安全性较低,容易受到 CSRF 攻击。

7. Window

  • 优点
    • 可以直接访问浏览器窗口和标签页,适合简单的数据传递。
    • 在同一源的标签页间可以直接通过 window.openerwindow.name 共享数据。
  • 缺点
    • 不适合复杂的数据共享,限制较多。
    • 依赖于窗口的打开方式,局限性大。
    • 难以管理多个标签页间的数据状态。

8. WebSocket

  • 优点
    • 实时双向通信,适合需要快速响应的数据共享。
    • 适合大规模和高频率的数据传输。
  • 缺点
    • 需要服务器支持,增加了实现的复杂性。
    • 可能涉及更多的安全性和连接管理问题。
    • 不适合简单的数据共享,通常用于更复杂的应用场景。


http://www.niftyadmin.cn/n/5708318.html

相关文章

idea如何拉取git仓库新的项目,有git仓库地址

在 IntelliJ IDEA 中拉取一个新的 Git 仓库项目&#xff0c;你可以按照以下步骤操作&#xff1a; 打开 IntelliJ IDEA。 如果你还没有打开任何项目&#xff08;即处于欢迎界面&#xff09;&#xff0c;请选择“Get from VCS”&#xff08;从版本控制系统获取&#xff09;。如果…

最经典无人机数据集

在现代科技的浪潮中&#xff0c;无人机技术就像一颗闪亮的星星&#xff0c;吸引了全球的目光。它们不仅在物流、农业、环境监测和灾害救援等领域大显身手&#xff0c;还为商业世界带来了无限可能。然而&#xff0c;随着无人机的数量不断增加&#xff0c;如何有效地管理和利用这…

MySQL 密码忘记了怎么办?

在使用 MySQL 的过程中&#xff0c;有时候我们可能会忘记密码。别担心&#xff0c;本文将详细介绍在 Windows 系统下如何重新设置 MySQL 密码。 一、停止 MySQL 服务 打开“服务”窗口&#xff0c;可以通过在 Windows 搜索栏中输入“服务”来找到并打开它。在服务列表中找到“…

OpenStack服务Swift重启失效(已解决)

案例分析Swift重启失效 1. 报错详情 在重新启动 VMware 虚拟机后&#xff0c;我们发现 OpenStack 的 Swift 服务出现了 503 Service Unavailable 错误。经过排查&#xff0c;问题根源在于 Swift 服务所使用的存储挂载是临时挂载&#xff0c;而非永久挂载。 Swift 服务依赖于…

Visual Studio 2022 配置 Boost 库

一、使用预编译版本 尽量不要使用预编译版本&#xff0c;因为可能构建的不完全&#xff0c;还得重新构建&#xff0c;不如一步到位 1. 下载预编译的 Boost 库 下载&#xff1a;Boost C Libraries - Browse /boost-binaries at SourceForge.net 2. 选择 msvc 版本&#xff0…

【PHP小课堂】一起学习PHP中的反射(一)

一起学习PHP中的反射&#xff08;一&#xff09; 反射这个名词相信大家不会陌生&#xff0c;但反过来说&#xff0c;这个反射到底是一个什么概念呢&#xff1f;其实反射&#xff0c;就是通过一些方法函数&#xff0c;来获得一个类或者一个实例化对象中的一些信息。当然&#xf…

Vue:监听视频播放时长

目录 1、源码2、监听视频实时时长3、监听视频播放时长4、监听视频暂停时长 1、源码 <template><el-dialog class"videoBox" :title"title" :visible.sync"visible" width"40%" :before-close"handleClose" :close…

2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明

2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明 2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明 文章目录 2.2.ReactOS系统KSERVICE_TABLE_DESCRIPTOR结构体的声明KSERVICE_TABLE_DESCRIPTOR系统调用表结构体的声明 KSERVICE_TABLE_DESCRIPTOR系统调用表结构体…