主頁(yè) > 知識(shí)庫(kù) > 詳解使用postMessage解決iframe跨域通信問(wèn)題

詳解使用postMessage解決iframe跨域通信問(wèn)題

熱門標(biāo)簽:惡搞電話機(jī)器人 電話機(jī)器人技術(shù) 地圖標(biāo)注軟件打印出來(lái) 欣鼎電銷機(jī)器人 效果 高德地圖標(biāo)注商戶怎么標(biāo) 黃石ai電銷機(jī)器人呼叫中心 ok電銷機(jī)器人 智能電銷機(jī)器人被禁用了么 如何查看地圖標(biāo)注

這周碰到一個(gè)讓人頭疼的需求:要在我的web項(xiàng)目中嵌入另一個(gè)第三方web項(xiàng)目。第一時(shí)間想到的就是用iframe了,但問(wèn)題來(lái)了,我和第三方web項(xiàng)目是有交互的,這就違反同源策略了,處理跨域問(wèn)題是最讓人頭疼的事之一。

需求是這樣的,在我的頁(yè)面點(diǎn)擊一些按鈕,要實(shí)時(shí)反饋到iframe子頁(yè)面,子頁(yè)面再進(jìn)行響應(yīng)。

當(dāng)時(shí)腦子里第一時(shí)間想到的解決方案是:用NGINX把兩個(gè)項(xiàng)目代理到同一域名下。但這樣似乎有點(diǎn)小題大做了,有沒(méi)有更方便快捷的方法呢?

在window對(duì)象下有個(gè)postMessage方法,是專門用來(lái)解決跨域通信問(wèn)題的。

關(guān)于postMessage的詳細(xì)介紹請(qǐng)戳這里,不過(guò)MDN的文檔太詳細(xì)了,導(dǎo)致有些同學(xué)看完還是一臉懵逼,下面我們就來(lái)看看怎么用postMessage實(shí)現(xiàn)iframe跨域通信,當(dāng)你會(huì)用了之后再回去看文檔,感覺是完全不同的。

首先我們模擬場(chǎng)景,假設(shè)有兩個(gè)不同源的頁(yè)面,iframePage.html是index.html的子頁(yè)面:

<!-- index.html -->

<body style="border:5px solid #333;">

  <h1>this is index</h1>

  <iframe src="./iframePage.html" id='myframe'></iframe>

</body>
<!-- iframePage -->

<body style="border:5px solid #333;">

  <h1>this is iframePage</h1>

</body>

現(xiàn)在這兩個(gè)iframe是無(wú)法通信,因?yàn)樗鼈兪遣煌吹模僭O(shè)存在跨域問(wèn)題),這時(shí)候就要用到postMessage了。

我們先試著從父頁(yè)面向子頁(yè)面發(fā)送一條消息:

// idnex.html

//獲取iframe元素
iFrame = document.getElementById('myframe')

//iframe加載完畢后再發(fā)送消息,否則子頁(yè)面接收不到message
iFrame.onload = function(){

  //iframe加載完立即發(fā)送一條消息
  iFrame.contentWindow.postMessage('MessageFromIndex1','*');

}

我們知道postMessage是掛載在window對(duì)象上的,所以等iframe加載完畢后,用iFrame.contentWindow獲取到iframe的window對(duì)象,然后調(diào)用postMessage方法,相當(dāng)于給子頁(yè)面發(fā)送了一條消息。

postMessage方法第一個(gè)參數(shù)是要發(fā)送的數(shù)據(jù),可以是任何原始類型的數(shù)據(jù)。

Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)之前,第一個(gè)參數(shù)必須是一個(gè)字符串。

postMessage方法第二個(gè)參數(shù)可以設(shè)置要發(fā)送到哪個(gè)url,如果當(dāng)前子頁(yè)面的url和設(shè)置的不一致,則會(huì)發(fā)送失敗,我們?cè)O(shè)置為*,代表所有url都允許發(fā)送。

postMessage方法還有第三個(gè)參數(shù),屬于高級(jí)用法,這里不做討論,可以稍后去MDN了解。

消息發(fā)送到iframePage.html,我們來(lái)接收message:

// iframePage.html

//回調(diào)函數(shù)
function receiveMessageFromIndex ( event ) {
  console.log( 'receiveMessageFromIndex', event )
}

//監(jiān)聽message事件
window.addEventListener("message", receiveMessageFromIndex, false);

我們只需要在子頁(yè)面監(jiān)聽message事件,并且設(shè)置好回調(diào)函數(shù)即可,來(lái)看看打印出來(lái)的event:

event對(duì)象中的data屬性存放著我們從父頁(yè)面?zhèn)鬟^(guò)來(lái)的數(shù)據(jù),就這么簡(jiǎn)單!

讓我們?cè)僭囋噺淖禹?yè)面發(fā)送數(shù)據(jù)給父頁(yè)面:

// iframePage.html

//給父頁(yè)面發(fā)送消息,data為對(duì)象
parent.postMessage( {msg: 'MessageFromIframePage'}, '*');

父頁(yè)面接收數(shù)據(jù):

//index.html

//回調(diào)函數(shù)
function receiveMessageFromIframePage (event) {
    console.log('receiveMessageFromIframePage', event)
}

//監(jiān)聽message事件
window.addEventListener("message", receiveMessageFromIframePage, false);

我看看到,的確可以傳輸不同的數(shù)據(jù),此時(shí)data為一個(gè)對(duì)象:

大家可以到postMessage-demo把代碼clone下來(lái)運(yùn)行試試看。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

標(biāo)簽:盤錦 綏化 中山 聊城 萍鄉(xiāng) 赤峰 阿壩 金昌

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解使用postMessage解決iframe跨域通信問(wèn)題》,本文關(guān)鍵詞  詳解,使用,postMessage,解決,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解使用postMessage解決iframe跨域通信問(wèn)題》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于詳解使用postMessage解決iframe跨域通信問(wèn)題的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章