1、同域限制
所謂“同域限制”是指,出于安全考慮,瀏覽器只允許腳本與同樣協(xié)議、同樣域名、同樣端口的地址進(jìn)行通信。
2、window.postMessage方法
瀏覽器限制不同窗口(包括iFrame窗口)之間的通信,除非兩個窗口裝載的是同一個域名下的網(wǎng)頁。window.postMessage方法就是為了解決這個問題而特定的API,可以讓不同域名的窗口互相通信。
postMessage方法的格式如下:
targetWindow.postMessage(message, targetURL[, transferObject]);
上面代碼的targetWindow是指向目標(biāo)窗口的變量,message是要發(fā)送的消息,targetURL是指定目標(biāo)窗口的網(wǎng)址,不符合該網(wǎng)址就不發(fā)送信息,transferObject則是跟隨信息一起發(fā)送的Transferable對象。
假定當(dāng)前網(wǎng)頁彈出一個新窗口。
var popup = window.open(...popup details ...);
然后在當(dāng)前網(wǎng)頁上監(jiān)聽message事件。
window.addEventListener('message', receiveMessage, false); function receiveMessage(e) { if (e.origin != 'http://example.org') { return; } console.log(e.data); }
上面的代碼指定message事件的回調(diào)函數(shù)是receiveMessage,一旦收到其他窗口發(fā)來的信息,receiveMessage函數(shù)就會被調(diào)用。receiveMessage函數(shù)接受一個event事件對象作為參數(shù),該參數(shù)里的origin屬性表示信息的來源網(wǎng)址,如果該網(wǎng)址不符合要求,就立刻返回。event.data屬性則包含了實(shí)際發(fā)送過來的信息。
event對象的屬性除了origin和data,還有一個source屬性,指向向當(dāng)前網(wǎng)頁發(fā)送信息的窗口對象。
接著,在當(dāng)前網(wǎng)頁上使用postMessage方法對新窗口發(fā)送信息。
popup.postMessage('hello world!', 'http://example.org');
上面代碼的postMessage方法的第一個參數(shù)是實(shí)際發(fā)送的信息,第二個參數(shù)是指定發(fā)送對象的域名必須是http://example.org。如果對方窗口不是這個域名,信息不會發(fā)送出去。
最后,在popup窗口中部署下面的代碼。
//popup 窗口function receiveMessage(event) { event.source.postMessage('Nice to see you!', '*'); } window.addEvengtListener('message', receiveMessage, false);
上面代碼有幾個地方需要注意。首先,receiveMessage函數(shù)里面沒有過濾信息的來源,任意網(wǎng)址發(fā)來的信息都會被處理。其次,postMessage方法中指定的目標(biāo)窗口的網(wǎng)址是一個星號,表示該信息可以向任意網(wǎng)址發(fā)送。通常來說,這兩種做法是不推薦的,因?yàn)椴粔虬踩?,可能會被對方過濾掉。
所有瀏覽器都支持這個方法,但是IE8和IE9只允許postMessage方法與iFrame窗口通信,不能與新窗口通信。IE10允許與新窗口通信,但是只能使用IE特有的MessageChannel對象