2012-09-28 39 views
9

我一直堅持了幾個小時。Chrome上的window.postMessage存在的問題

我在http://example.com上有一個包含iframe的src到 b.html的http://subdomain.example.com上的a.html。 a.html有一些JS代碼 來postMessage到iframe。

的代碼的postMessage很簡單:

iframe_window.postMessage('message', iframe_element.src) 

不過這樣一來,Chrome瀏覽器將引發一個錯誤:

Unable to post message to http://subdomain.example.com. Recipient has origin null. 

我也曾嘗試:

iframe_window.postMessage('message', 'http://subdomain.example.com') 

,但沒有運氣!

這是它的工作的唯一辦法:

iframe_window.postMessage('message', '*') 

但我聽說過「*」是不是很好用。

Firefox中沒有問題。

+0

只是爲了澄清,在你的實際代碼中,你使用的是真實的網站嗎? –

回答

15

它看起來像這可能是一個問題,在發送信號時未加載子iframe,因此iframe.src沒有正確的值。

我做了一些測試,並得到了與您相同的錯誤,但是當我在setTimeout中包裝postMessage調用並等待100ms時,則沒有錯誤,這告訴我這是一個初始化競爭條件。

下面是如何實現的,而不setTimeout的一個清潔的解決方案:

家長:

window.addEventListener("DOMContentLoaded", function() { 

    var iframe = document.querySelector("iframe") 
     , _window = iframe.contentWindow 

    window.addEventListener("message", function(e) { 

     // wait for child to signal that it's loaded. 
     if (e.data === "loaded" && e.origin === iframe.src.split("/").splice(0, 3).join("/")) { 

      // send the child a message. 
      _window.postMessage("Test", iframe.src) 
     } 
    }) 

}, false) 

兒童:

window.addEventListener("DOMContentLoaded", function() { 

    // signal the parent that we're loaded. 
    window.parent.postMessage("loaded", "*") 

    // listen for messages from the parent. 
    window.addEventListener("message", function(e) { 

     var message = document.createElement("h1") 

     message.innerHTML = e.data 

     document.body.appendChild(message) 

    }, false) 

}, false) 

這是一個簡單的解決方案,其中,孩子會發信號給任何人它被加載(使用「*」,這是可以的,因爲沒有敏感的被髮送。)父母監聽一個加載的事件並檢查它是它的孩子在這發射它。

父母然後發送消息給準備接收它的孩子。當孩子得到消息時,它將數據放入<h1>並將其附加到<主體>。

我在Chrome中使用實際的子域名測試了此解決方案,該解決方案適用於我。

+0

第一句話'看起來像這可能是一個問題,在發送信號時未加載子iframe'是我需要獲得iframe通信工作的線索......謝謝! – RamRaider