跨文件訊息傳送(cross-document messaging),有時候也簡稱為XDM,指的是來自不同網域的頁間傳遞訊息。例如,www.w3cmm.com網域中的一個頁面與一個位於內嵌框架中的p2p.w3cmm.com網域中的頁面通訊。在XDM機制出現之前,更穩健地實現這種通訊需要花費很多功夫。 XDM把這種機制規範化,讓我們能既穩健簡單地實現跨文檔通訊。
XDM的核心是postMessage()方法。在HTML5規範中,除了XDM部分之外的其它部分也會提到這個方法名,但都是為了同一個目的:向另一個地方傳遞資料。對於XDM而言,「另一個地方」指的是包含在目前頁面中的d5ba1642137c3f32f4f4493ae923989c元素,或由目前頁面彈出的視窗。
postMessage()方法接收兩個參數:一則訊息和一個表示訊息接收方來自哪個網域的字串。第二個參數對保障安全通訊非常重要,可以防止瀏覽器把訊息送到不安全的地方。來看下面的例子。
var iframWindow = document.getElementById("myframe").contentWindow; iframWindow.postMessage("A secret", "http://www.w3cmm.com");
最後一行程式碼嘗試向內嵌框架中傳送一則訊息,並指定框架中的文件必須來自「http://www.w3cmm.com」網域。如果來源匹配,訊息會傳遞到內嵌框架中;否則,postMessage()什麼都不做。這個限制可以避免視窗中的位置在你不知道的情況下改變。如果傳給postMessage()的第二個參數是“*”,則表示可以把訊息傳送給來自任何網域的文檔,但我們不建議這樣做。
接收到XDM訊息時,會觸發window物件的message事件。這個事件是以非同步形式觸發的,因此從發送訊息到接受訊息(觸發接受視窗的message事件)可能要經過一段時間的延遲。觸發message事件後,傳遞給onmessage處理程序的事件物件包含以下三個方面的重要資訊。
data:作為postMessage()第一個參數傳入的字串資料。
origin:傳送訊息的文件所在的網域,例如「http://www.w3cmm.com」。
source:傳送訊息的文檔的window物件的代理。這個代理物件主要用於在傳送上一則訊息的視窗中呼叫postMessage()方法。如果發送訊息的視窗是來自同一個網域,那這個物件就是window。
接受到訊息後驗證發送視窗的來源是至關重要的。就像給postMessage()方法指定第二個參數,以確保瀏覽器不會把訊息傳送給未知頁面一樣,在onmessage處理程序中偵測訊息來源可以確保傳入的訊息來自已知的頁面。基本的檢測模式如下。
var EventUtil = { addHandler: function (element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } } }; EventUtil.addHandler(window, "message", function (event) { //确保发送消息的域是已知的域 if (event.origin == "http://www.w3cmm.com") { //处理接收到的数据 processMessage(event.data); //可选:向来源窗口发送回执 event.source.postMessage("Received!", "http://p2p.w3cmm.com"); } });
還是要提醒大家,event.source大多數情況下只是window物件的代理,並非實際的window物件。換句話說,不能透過這個代理對象存取window物件的其它任何資訊。記住,只透過這個代理呼叫postMessage()就好,這個方法永遠不存在,永遠可以呼叫。
XDM還有一些怪異之處。首先,postMessage()第一個參數最早是作為「永遠都是字串」來實現的。但後來這個參數的定義改了,改成允許傳入任何資料結構。可是,並非所有瀏覽器都實現了這項變更。為保險起見,使用postMessage()時,最好還是只傳字串。如果你想傳入結構化的數據,最佳選擇是先在要傳入的資料上呼叫JSON.stringify(),透過postMessage()傳入得到的字串,然後再在onmessage事件處理程式中呼叫JSON.parse()。
在透過內嵌框架載入其它網域的內容時,使用XDM是非常方面的。因此,在混搭和社交網路應用中,這種傳遞訊息的方法極為常用。有了XDM,包含d5ba1642137c3f32f4f4493ae923989c的頁面可以確保自身不受惡意內容的侵擾,因為它只透過XDM為嵌入的框架通訊。而XDM也可以來自相同網域的頁間使用。
以上是詳細介紹HTML5中的跨文件訊息傳遞的詳細內容。更多資訊請關注PHP中文網其他相關文章!