跨文件訊息傳送,簡稱為xdm,指的是來自不同的域的頁面間的傳遞訊息。
如果兩個網頁不同源,就無法拿到對方的
dom。典型的例子是
iframe
視窗和window.open
方法開啟的視窗,它們與父視窗無法通訊。比如,
父視窗執行下面的命令,如果
iframe
視窗不是同源將會報錯。
document.getelementbyid("iframe").contentwindow.document
上面命令中,父視窗想獲取子視窗的
dom,因為跨源導致報錯。
反之亦然,子視窗獲取主視窗的
dom也會報錯。
window.parent.document.body
如果兩個視窗一級網域名稱相同,只是二級網域名稱不同,那麼設定
document.domain
屬性,就可規避同源政策,拿到
dom。而
對於完全不相同的**,目前有三種方法,可以解決跨域視窗的通訊問題。
(1) 片段識別符(
fragment identifier
)
片段識別符指的是,url的#號後面的部分,即hash部分,比如
#fragment
的#fragment。如果只是改變片段識別符號,頁面將不會重新重新整理,
父視窗可以把資訊,寫入子視窗的片段識別符號。
var src = originurl+'#'+data;
document.getelementbyid('iframe').src = src;
子視窗通過監聽hashchange事件得到通知
window.onhashchange = checkmessage;
function checkmessage()
同樣的,子視窗也可以改變父視窗的片段識別符號。
parent.location.href = target+"#"+hash;
(2)
window.name
瀏覽器視窗有window.name屬性。
這個屬性的最大特點是,無論是否同源,只要在同乙個視窗裡,前乙個網頁設定這個屬性,後乙個網頁就可以讀取它。
父視窗先開啟乙個子視窗,載入乙個不同源的網頁,該網頁將資訊寫入window.name屬性。
window.name = data;
接著,子視窗跳回乙個與主視窗同域的**。
location = '';
然後,主視窗就可以讀取子視窗的window.name了。
var data = document.getelementbyid('iframe').contentwindow.name;
這種方法的優點是,window.name容量很大,可以放置非常長的字串;缺點是必須監聽子視窗window.name屬性的變化,會影響網頁效能。
(3) 跨文件通訊api(cross-document messaging)
上面兩種方法都屬於破解,
html5
為解決這個問題,引入乙個全新的
api:跨文件通訊
api(
cross-document messaging)這個
api為
window
物件新增了
乙個window.postmessage
方法,允許跨視窗通訊,不論這兩個視窗是否同源。postmessage()方法接收兩個引數:一條訊息和乙個表示訊息接收方來自哪個域的字串,第二個引數對保障安全通訊非常重要,可以防止瀏覽器把訊息傳送到不安全的地方。
舉例來說
,父視窗向子視窗傳送訊息,呼叫postmessage方法即可。
var popup =window.open('','title');
popup.postmessage('hello world!','');
postmessage方法的第乙個引數是具體的資訊內容,第二個引數是接受訊息的視窗的源
(origin),即「
協議+網域名稱+
埠」。也可以設為
「*」,表示不限制網域名稱,向所有視窗傳送。
子視窗向
父視窗髮型訊息的寫法類似。
window.opener.postmessage('nice to see you','');
接收到xdm的訊息時,會觸發window物件的message事件,這個事件以非同步形式觸發,所以可能會發生一些延遲。
觸發message
事件後,傳遞給onmessage處理程式的事件物件
event包含以下三方面的重要資訊
:(1).event.source:傳送訊息的視窗
(2).event.origin:訊息發向的**
(3).event.data:訊息內容
父視窗和子視窗可以通過message
事件,監聽
對方的訊息。
window.addeventlistener('message',function(e),false);
下面的例子
是,子視窗通過event.source
屬性應用父視窗,然後傳送訊息。
window.addeventlistener('message',receivemessage);
function receivemessage(event)
event.origin屬性可以過濾不是發給本視窗的訊息。
window.addeventlistener('message',receivemessage);
function receivemessage(event)else
}片段識別符指的是,url的#號後面的部分,比如
#fragment
的#fragment。如果只是改變片段識別符號,頁面將不會重新重新整理、
父視窗可以把資訊,寫入子視窗的片段識別符號。
var src = originurl+'#'+data;
document.getelementbyid('iframe').src = src;
子視窗通過監聽hashchange事件得到通知
window.onhashchange = checkmessage;
function checkmessage()
同樣的,子視窗也可以改變父視窗的片段識別符號。
parent.location.href = target+"#"+hash;
js跨域 ajax跨域 跨域方式(前端)
跨域方式 cors 跨域資源共享 當使用xmlhttprequest傳送請求時,瀏覽器會自動加上乙個請求頭 origin,後端在接受到請求後確定響應後會在response headers中加入乙個屬性 access control allow origin,值就是發起請求的源位址 瀏覽器得到響應會進...
html5跨文件訊息傳遞(可實現跨域)
跨文件訊息傳送 cross document messaging 簡稱xdm,指的是來自不同域的頁面間傳遞訊息。xdm的核心是postmessage 方法。目的 向另乙個地方傳遞資料。對於xdm而言,另乙個地方 指的是包含在當前頁面中的元素,或者由當前頁面彈出的視窗。postmessage 方法接收...
前端跨域策略
假設頁面和屬於不同域,a頁面請求b頁面的內容.利用document.domain實現跨域的前提是這兩個網域名稱必須屬於同乙個基礎網域名稱,協議埠都要一致。主要是父域和子域之間的通訊 此時雖然能正確得到window.name的值,但是由於每次iframe.src的載入都執行iframe.onload,...