前端跨域技術之跨文件訊息傳輸

2021-07-11 16:21:48 字數 3197 閱讀 4029

跨文件訊息傳送,簡稱為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,...