使用 postMessage + iframe 實現跨域通信


一、postMessage

window.postMessage() 方法可以安全地實現跨源通信。通常,對於兩個不同頁面的腳本,只有當執行它們的頁面位於具有相同的協議(通常為https),端口號(443為https的默認值),以及主機(兩個頁面的模數 Document.domain設置為相同的值)時,這兩個腳本才能相互通信。window.postMessage() 方法提供了一種受控機制來規避此限制,只要正確的使用,這種方法就很安全。

調用 postMessage() 方法時,向目標窗口派發一個 Event 消息。 該 Event 消息的 data 屬性為 postMessage() 的數據;origin 屬性表示調用 postMessage() 方法的頁面的地址。

二、語法

otherWindow.postMessage(message, targetOrigin)

說明

  • otherWindow:其他窗口的一個引用,比如 iframe 的 contentWindow 屬性、執行 window.open 返回的窗口對象、或者是命名過或數值索引的 window.frames。
  • message:將要發送到其他 window 的數據。它將會被結構化克隆算法序列化。這意味着你可以不受什么限制的將數據對象安全的傳送給目標窗口而無需自己序列化。
  • targetOrigin:通過窗口的 origin 屬性來指定哪些窗口能接收到消息事件,其值可以是字符串 * (表示無限制)或者一個 URI。在發送消息的時候,如果目標窗口的協議、主機地址或端口這三者的任意一項不匹配 targetOrigin 提供的值,那么消息就不會被發送;只有三者完全匹配,消息才會被發送。

三、示例

我配了兩個域名 example.mazey.cnexample0.mazey.cn,其中 http://example0.mazey.cn/post-message/send.html 會給 http://example.mazey.cn/post-message/receive.html 發送一條消息 Message From Mazey.

send.html

<script>
  window.onload = function () {
    window.parent.postMessage(
      'Message From Mazey.',
      '*'
    )
  }
</script>

receive.html

<script>
  // 監聽
  window.addEventListener(
    'message',
    event => {
      let origin = event.origin || event.originalEvent.origin
      console.log(event, origin, event.data) // MessageEvent{...} "http://example0.mazey.cn" "Message From Mazey."
    }
  )
  // 使用 JS 加載 iframe,保證監聽創建后再加載 iframe。
  let iframeEle = document.createElement('iframe')
  iframeEle.src = 'http://example0.mazey.cn/post-message/send.html'
  iframeEle.style = 'border: none;width: 0;height: 0;'
  document.body.insertBefore(iframeEle, document.body.firstChild)
</script>

注意

如果發送的消息有敏感信息(例如:密碼),始終驗證接受時的 event.origin 和指定發送時的 targetOrigin。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM