如果兩個 URL 具有相同的協定,域,和端口,則稱它們是
同源
的。
以下幾個URL是同源的:
- site.com
- site.com/
- site.com/a/index.htm…
以下是不同源的:
- https://site.com
- http://bbs.site.com
- site.com:8080
- http://site.org
同源政策規定:
- 如果我們有對另一個視窗的引用(window.open || iframe),并且該視窗是同源的,那麼我們就具有對該視窗的全部通路權限。
- 如果不是同源的,我們就不能通路視窗中的内容:變量,文檔,任何東西。唯一例外是location:我們可以修改它,使用它進行重定向。但是我們無法讀取 location 。是以,我們無法看到使用者目前所處的位置,也就不會洩露任何資訊。
iframe的通信離不開postMessage,下面聊一聊postMessage onmessage。
postMessage onmessage
想要發送消息的視窗需要調用接收視窗的
postMessage
方法。換句話說,如果我們想把消息發送給
win
,我們應該調用
win.postMessage(data, targetOrigin)
。
參數
data
要發送的資料。可以是任何對象,資料會被通過使用“結構化序列化算法(structured serialization algorithm)”進行克隆。IE 浏覽器隻支援字元串,是以我們需要對複雜的對象調用
JSON.stringify
方法進行處理,以支援該浏覽器。
targetOrigin
指定目标視窗的源,以便隻有來自給定的源的視窗才能獲得該消息。
// <iframe src="http://127.0.0.1:8080/2.html" name="example" />
let win = window.frames.example;
win.postMessage("message", "http://127.0.0.1:8080");
為了接收消息,目标視窗應該在
message
事件上有一個處理程式。當
postMessage
被調用時觸發該事件(并且
targetOrigin
檢查成功)。
event 對象具有特殊屬性:
-
從data
傳遞來的資料。postMessage
-
發送方的源,例如origin
。http://javascript.info
-
對發送方視窗的引用。如果我們想,我們可以立即source
回去。source.postMessage(...)
window.addEventListener("message", function(event) {
console.log(event)
if (event.origin != 'http://http://127.0.0.1:8080') {
// 來自未知的源的内容,我們忽略它
return;
}
if (window == event.source) {
// chrome 下, 頁面初次加載後會觸發一次 message 事件, event.source 是 window 對象
// 此時 event.source.postMessage 會形成死循環
// 是以,要跳過第一次的初始化觸發的情況
return
}
console.log( "received: " + event.data );
// 可以使用 event.source.postMessage(...) 向回發送消息
event.source.postMessage('i am 2.html')
}, source);