2011-07-19 38 views
1

我們有一些代碼正在利用HTML 5中的新功能postMessage來解決跨域通信問題。我試圖找到一種方法來檢測我是否將消息發佈到正確加載其內容的iFrame。如果幀無法正確加載,postMessage不知道這一點,並將愉快地發送消息到無響應幀(我假設消息正在傳遞到幀,而不管它是否加載內容)。HTML 5 PostMessage /檢測iFrame無法加載

這是我們的工作流程:

  1. 用戶負載http://www.a.com/specialpage.aspx
  2. a.com/specialpage.aspx依次加載一個孩子的iFrame與它的源設置爲從另一個域的代理頁,說http://www.b.com/lookatmyproxy.htm作爲例。
  3. 用戶做了一些動作,點擊一個按鈕
  4. window.postMessage是用來發布消息到子框架,它是(希望)由代理框架加載(b.com/lookatmyproxy。 HTM)。收到該郵件後,將對郵件進行驗證,處理,並將回覆郵件發送回父框架(a.com/specialpage.aspx)。
  5. 用戶顯示他們的行動結果,每個人都很高興。

問題的情況是,如果b.com下跌和代理未能在iFrame中加載,postMessage的將剛剛火,忘記和父框架從來沒有收到任何類型的錯誤或答覆。 iframe的安全性問題和性質似乎阻止我檢查幀內容或狀態,以確定代理是否正確加載。我可以在a.com和b.com之間放置一些帶有超時邏輯的中繼(a.com發佈到a.com/relay,然後發佈到b.com/proxy等) ,但似乎過於複雜。

有沒有辦法讓我檢查iFrame並告訴它的內容正確加載,或者檢測到postMessage傳遞給源代碼未加載的框架?

回答

2

這不是最乾淨的答案,但我能夠解決我的問題。我發現的是一些舊的文檔,雖然安全性不允許您從其他框架讀取信息,但您可以調用一些功能。在較舊的瀏覽器中,這被用來欺騙框架來設置每個其他URL片段並導致行爲發生。一個很好的參考是在這裏:

http://softwareas.com/cross-domain-communication-with-iframes

由於PostMessage一允許,我代理做的第一件事就是發佈「加載」消息給它的父框架,如果它的存在。代理看起來是這樣的:

//tell the parent that we're functional 
var data = '{ "action" : "Loaded" }'; 
if (parent && parent.frames && parent.frames[0] && parent.frames[0].content) { 
    parent.frames[0].content.postMessage(data, '*'); 
} 

window.addEventListener("message", function (e) { 
    if (e.domain == undefined) { 
     //do something 
    } 
}, false); 

對事物的另一面,我的網頁,收聽該消息,並設置一個變量,當他們收到它表明代理正確加載。如果他們從未收到該消息,則所有操作都假定該代理不可用,並且UI會作出相應反應以阻止用戶操作。看起來像這樣:

$(document).ready(function() { 
    window.addEventListener("message", function (e) { 
     var args = (e.data && (e.data.length > 0)) ? JSON.parse(e.data) : {}; 
     if (args.action) { 
      if (args.action == 'Loaded') { 
       if (typeof ProxyLoaded_success == 'function') { 
        ProxyLoaded_success(args); 
       } 
      } 
     } 
    }, false); 
}); 

var proxyLoaded = false; 
function ProxyLoaded_success(args) { 
    proxyLoaded = true; 
} 

function abc() { 
    if(proxyLoaded == true) { 
     //do something here 
    } else { 
     alert("proxy didn't load. call support"); 
    } 
}