浏览器窗口间的通信

一、汇总

浏览器窗口间的通信_第1张图片

二、同源策略

浏览器窗口间的通信_第2张图片

三、webSocket (无跨域限制)

优点:无跨域限制
缺点:成本高
浏览器窗口间的通信_第3张图片

四、客户端存储

1、localStorage + onStorage

浏览器窗口间的通信_第4张图片
浏览器窗口间的通信_第5张图片

例子:
浏览器窗口间的通信_第6张图片

浏览器窗口间的通信_第7张图片

2、定时器 + 客户端存储

浏览器窗口间的通信_第8张图片

例子:
浏览器窗口间的通信_第9张图片
浏览器窗口间的通信_第10张图片

浏览器窗口间的通信_第11张图片

缺点:
浏览器窗口间的通信_第12张图片

五、postMessage (无跨域限制)

浏览器窗口间的通信_第13张图片

例子:
浏览器窗口间的通信_第14张图片
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>

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>

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

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

核心代码:
浏览器窗口间的通信_第15张图片

例子:
浏览器窗口间的通信_第16张图片

<body>
    <section>
      <iframe src="./page1.html">iframe>
      <iframe src="./page2.html">iframe>
    section>
  body>
<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>
  <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>

七:MessageChannel (无跨域限制)

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

核心代码:
浏览器窗口间的通信_第17张图片

例子:
浏览器窗口间的通信_第18张图片

<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>
<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>

八、SharedWorker

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

例子:
浏览器窗口间的通信_第19张图片

浏览器窗口间的通信_第20张图片
浏览器窗口间的通信_第21张图片
浏览器窗口间的通信_第22张图片
浏览器窗口间的通信_第23张图片

你可能感兴趣的:(JavaScript,javascript,前端)