【postMessage】跨源通信

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

語法

otherWindow.postMessage(message, targetOrigin, [transfer]);

使用

打開窗口
let popup =  window.open( process.env.VUE_APP_MEDIAASSET_PATH + '/applicationContent/index', "", "width=1000, height=700, top=30, left=50" )
設置domain
document.domain = process.env.VUE_APP_DOMAIN

說明:雙方都要設置;而且如果雙方不同源時,一定要設置。

父向子發送
let that = this 
      this.timer = window.setTimeout(function (params) {
        popup.postMessage({
          clientId: 'apollo',
          templateId: 'game_card'
        }, process.env.VUE_APP_MEDIAASSET)
      }, 3000)
子接收父
      window.addEventListener('message',function(e) { 
        console.log('---e', e)
        if (e.origin === process.env.VUE_APP_MEDIAASSET) {
        //操作
           that.postSource = e.source
        }
      });
子向父發送
this.postSource.postMessage(list, process.env.VUE_APP_APOLLO); //反過來向父頁面傳消息
父接收子
const that = this;
      window.addEventListener('message',function(e) { 
        console.log('e--', e);
        if (e.origin === process.env.VUE_APP_APOLLO) {
          that.clearTimeout(that.timer)
          that.contentList = e.data;
        }
      });
相關參數設置
VUE_APP_MEDIAASSET_PATH = 'https://web-dev.mamp.xxx.org/edit/index.html#'
VUE_APP_MEDIAASSET = 'https://web-dev.mamp.xxx.org'
VUE_APP_DOMAIN = 'xxx.org'
VUE_APP_APOLLO = 'https://apollo-dev.xxx.org'

注意

1、document.domain設置
兩個文檔,只有在 document.domain 都被設定爲同一個值,表明他們打算協作;或者都沒有設定 document.domain 屬性並且URL的域是一致的 (如何判斷一致),這兩種條件下,一個文檔纔可以去訪問另一個文檔。如果沒有這個特殊的策略,每一個站點都會成爲他的子域的 XSS 攻擊的對象(例如,https://bugzilla.mozilla.org 可以被來自 https://bug*.bugzilla.mozilla.org 站點的 bug 附件攻擊)。
2、message
將要發送到其他 window的數據。它將會被結構化克隆算法序列化。這意味着你可以不受什麼限制的將數據對象安全的傳送給目標窗口而無需自己序列化。
在一下幾種情況下會報錯:

  • Function objects cannot be duplicated by the structured clone algorithm; attempting to throws a DATA_CLONE_ERR exception.
  • Cloning DOM nodes likewise throws a DATA_CLONE_ERR exception.
  • Certain object properties are not preserved:
    • The lastIndex property of RegExp objects is not preserved.
    • Property descriptors, setters, getters, and similar metadata-like features are not duplicated. For example, if an object is marked readonly with a property descriptor, it will be read/write in the duplicate, since that's the default.
    • The prototype chain is not walked or duplicated.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章