• 浏览器窗口间的通信


    一、汇总

    在这里插入图片描述
    网页和多标签tab的通讯:websocket、onStorage、sharedWorker、broadCast Channel、postMessage、cookie定时器轮询…
    网页和iframe之间的通信:postMessage、broadCast Channel…

    二、同源策略

    在这里插入图片描述

    三、webSocket (无跨域限制)

    优点:无跨域限制
    缺点:成本高
    在这里插入图片描述

    四、客户端存储

    1、localStorage + onStorage

    在这里插入图片描述
    在这里插入图片描述

    例子:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    如果修改的值未发生改变,window.onstorage 事件将不会触发

    2、定时器 + 客户端存储

    在这里插入图片描述

    例子:
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    缺点:
    在这里插入图片描述

    五、postMessage (无跨域限制)

    在这里插入图片描述

    例子:
    在这里插入图片描述
    index.html

    <body>
        <div>
            <iframe src="./ifr.html" id="ifr" style="width:600px; height:300px">iframe>
        div>
    
        主窗口
        
        <div>
            <div>Message:div>
            <div id="messages">div>
        div>
        <script>
            window.addEventListener("message", function (event) {
                messages.innerHTML += `
                    
    ${event.data}
    `
    }) setInterval(() => { ifr.contentWindow.postMessage(`message from index.html, ${Date.now()}`) }, 5000)
    script> body>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    ifr.html

    <body>
        iframe窗口
        <div>
            <div>Message:div>
            <div id="messages">div>
        div>
        <script>
            window.addEventListener("message", function (event) {
                messages.innerHTML += `
                    
    ${event.data}
    `
    }) setInterval(()=> { window.parent.postMessage(`message from ifr.html, ${Date.now()}`) }, 5000)
    script> body>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    六、Broadcast Channel 事件广播 超级好用!!!

    • 允许同源的不同浏览器窗口、Tab页、frame或者iframe下的不同文档之间相互通信
    • 缺点:同源策略

    核心代码:
    在这里插入图片描述

    例子:
    在这里插入图片描述

    <body>
        <section>
          <iframe src="./page1.html">iframe>
          <iframe src="./page2.html">iframe>
        section>
      body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    <body>
      <h3>Page 1h3>
      
      <section style="margin-top:50px; text-align: center">
        <input id="inputMessage" value="page 1的测试消息" />
        <input type="button" value="发送消息" id="btnSend" />
        <section id="messages">
          <p>收到的消息:p>
        section>
      section>
    
      <script>
        var messagesEle = document.getElementById("messages")
        var messageEl = document.getElementById("inputMessage")
        var btnSend = document.getElementById("btnSend")
        
        var channel = new BroadcastChannel("channel-BroadcastChannel")
        channel.addEventListener("message", function (ev) {
          var msgEl = document.createElement("p")
          msgEl.innerText =
            ev.data.date + " " + ev.data.from + ":" + ev.data.message
          messagesEle.appendChild(msgEl)
        })
    
        btnSend.addEventListener("click", function () {
          var message = messageEl.value
          channel.postMessage({
            date: new Date().toLocaleString(),
            message,
            from: "page 1"
          })
        })
      script>
    body>
    
    • 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
    • 34
      <body>
        <h3>Page 2h3>
    
        <section style="margin-top:50px; text-align: center">
          <input id="inputMessage" value="page 2的测试消息" />
          <input type="button" value="发送消息" id="btnSend" />
          <section id="messages">
            <p>收到的消息:p>
          section>
        section>
    
        <script>
          var messagesEle = document.getElementById("messages")
          var messageEl = document.getElementById("inputMessage")
          var btnSend = document.getElementById("btnSend")
          
          var channel = new BroadcastChannel("channel-BroadcastChannel")
          channel.addEventListener("message", function(ev) {
            var msgEl = document.createElement("p")
            msgEl.innerText = ev.data.date + " " + ev.data.from + ":" + ev.data.message
            messagesEle.appendChild(msgEl)
          })
    
          btnSend.addEventListener("click", function() {
            var message = messageEl.value
            channel.postMessage({
              date: new Date().toLocaleString(),
    
              message,
              from: "page 2"
            })
          })
        script>
      body>
    
    • 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
    • 34

    七:MessageChannel (无跨域限制)

    • Channel Messaging API 的 MessageChannel接口允许我们创建一个新的消息通道,并通过它的两个MessagePort属性发送数据
    • 缺点: 需要先创建联系

    核心代码:
    在这里插入图片描述

    例子:
    在这里插入图片描述

    <body>
        <iframe id="ifr" src="./ifr.html" style="width:600px; height:300px">iframe>
    
        <div>主窗口div>
    
        <div>
            <div>Message:div>
            <div id="messages">div>
        div>
    
        <script>
            const channel = new MessageChannel()
    
            var ifr = document.querySelector('iframe')
    
            ifr.onload = function () {
                ifr.contentWindow.postMessage('__init__', '*', [channel.port2])
            }
            // 监听消息
            channel.port1.onmessage = onMessage
            function onMessage(e) {
                messages.innerHTML += `
                    
    ${event.data}
    `
    } // 轮询发送 setInterval(function(){ channel.port1.postMessage(`message from index.html, ${Date.now()}`) }, 5000)
    script> body>
    • 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
    <body>
        iframe窗口
        <div>
            <div>Message:div>
            <div id="messages">div>
        div>
        <script>
            window.addEventListener("message", function (event) {
                if (event.data === "__init__") {
                    initChannel( event.ports[0])
                }
            })
            function initChannel(port) {
                port.onmessage = function (event) {
                    messages.innerHTML += `
                    
    ${event.data}
    `
    port.postMessage(`message from the iframe, ${Date.now()}`); } }
    script> body>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    八、SharedWorker

    • SharedWorkerWeb Worker的一种, 可单独开启一个进程,用于同域页面通讯
    • Web Worker可开启子进程执行JS,但不能操作DOM
    • 缺点:兼容性、同源策略

    例子:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    CSS3 的选择器、盒子模型、过渡、渐变、旋转、转换
    计算机网络
    数字孪生智慧工厂三维可视化系统解决方案,打造新一代智慧工厂
    阿里三面惨虐,spring,jvm,mybatis,并发编程等一窍不通
    从头训练一个神经网络!教它学会莫奈风格作画!⛵
    从JVM角度看继承
    ClickHouse 数据插入、更新与删除操作 SQL
    2024年:如何根据项目具体情况选择合适的CSS技术栈
    Unity 3D 简易对象池
    分布式和微服务
  • 原文地址:https://blog.csdn.net/weixin_44582045/article/details/132171143