因爲同源策略的限制,JavaScript跨域的問題,一直是一個頗爲棘手的問題,爲了解決js的跨域,web開發人員是煞費苦心,研究了各類跨域方案,若是有機會的話,明河之後會一一展現給各位,今天明河重點介紹下html5新引入的postMessage跨域方案。php
明河這二週在處理淘寶添加收藏夾的重構,裏面就有一個很是經典的跨域問題。
添加收藏彈出層外層是淘寶商城頁面域名是tmall.com,而彈出層內部的頁面域名倒是taobao.com,接下來的問題就是我如今但願彈出層內部的高度改變了,父頁面彈出層的高度也隨之改變,同時子iframe內有辦法使用一個按鈕,關閉父頁面的彈出層。
這個場景仍是很是經典的,不少朋友估計多多少少都會遇到這個狀況,就是有個彈出層裏面嵌一個iframe,iframe內的子頁面如何操做父頁面的彈出層或其餘元素?html
因爲今天主要是講html5的跨域方案,這裏明河簡要提一下,有機會跟你們詳細分享。
淘寶商城有個專門用於處理跨域的js類TMall.XDomain,這個類會生成子iframe中生成一個新的iframe,這個iframe咱們叫它代理iframe,代理iframe必須跟父頁面時同域的,這樣代理iframe就有權限處理父頁面。
這裏明河推薦閱讀如下文章:html5
postMessage是html爲了解決跨域通訊,特別引入的一個新的API,目前支持這個API的瀏覽器有:Firefox, IE8+, Opera, Safari, Chrome。postMessage容許頁面中的多個iframe/window的通訊,postMessage也能夠實現ajax直接跨域,不經過服務器端代理。java
感謝蘇河哥哥提供另外個主機做爲跨域測試,O(∩_∩)O哈!
在上面的demo中,明河簡單演示了postMessage的用法,父頁面中有二個不一樣域的iframe,如今咱們要求這二個iframe每過一秒,向對方的內容層傳遞一行文字,對象一接收到文字就開始輸出。web
這裏以iframe1.html的代碼爲例。ajax
var message = ‘hello,RIA之家! ‘ + (new Date().getTime());
window.parent.frames[1].postMessage(message, ‘*’);
iframe1.html須要向iframe2.html發送消息,也就是第二個iframe,因此是window.parent.frames[1],若是是向父頁面發送消息就是window.parent。
postMessage這個函數接收二個參數,缺一不可,第一個參數即你要發送的數據,第二個參數是很是重要,主要是出於安全的考慮,通常填寫容許通訊的域名,這裏明河爲了簡化,因此使用’*',即不對訪問的域進行判斷。跨域
iframe2.html中寫個監聽message事件,當有消息傳到iframe2.html時就會觸發這個事件。
var onmessage = function(e) {
var data = e.data,p = document.createElement(‘p’);
p.innerHTML = data;
document.getElementById(‘display’).appendChild(p);
};
//監聽postMessage消息事件
if (typeof window.addEventListener != ‘undefined’) {
window.addEventListener(‘message’, onmessage, false);
} else if (typeof window.attachEvent != ‘undefined’) {
window.attachEvent(‘onmessage’, onmessage);
}
整個通訊過程就結束了!是否是很是簡單愜意!
若是你有加域名限,好比下面的代碼:
window.parent.frames[1].postMessage(message, ‘http://www.36ria.com’);
就要在onmessage中追加個判斷:
if(event.origin !== http://www.36ria.com’) return;瀏覽器
html5的postMessage至關強悍和易用!你能夠利用這個特性解決大部分場景下的跨域問題,不用再建立個代理iframe之類的繁瑣方法。嚴重推薦你們練習下該方法,目前的確存在瀏覽器差別問題,但相信之後會成爲主流跨域通訊方案。安全