React常見跨窗口通信方式實例詳解
iframe
跨窗口通信就是在嵌套了iframe的時候,實現(xiàn)iframe與父窗口的通信。
什么是iframe
- 它是一個
html標(biāo)簽,它可以將一個網(wǎng)站作為一個dom元素,嵌入到另一個網(wǎng)站中。 iframe具有自己的window與document對象。
使用場景
- 比如公司開發(fā)了一個完整的網(wǎng)站,需要在另一個項目中去使用。比如直播功能,一些插件,這時候就可以使用
iframe嵌入的方式。減少了重復(fù)開發(fā)的時間,需要修改界面的時候,也只需要修改一份代碼即可。 - 微應(yīng)用,微應(yīng)用也有很多是使用
iframe來實現(xiàn)。
同源策略
當(dāng)兩個網(wǎng)站同時滿足:同協(xié)議+同域名+同端口的時候。
當(dāng)iframe與父窗口同源時
- 父窗口可以對
iframe進(jìn)行完全訪問,如window,document,location等對象的訪問。 - 父窗口可以調(diào)用
iframe的全局函數(shù)。 - 父窗口可以修改
iframe的元素內(nèi)容
效果圖
index1.html嵌套同源的index2.html
html1
<body>
<h1>html-1</h1>
<iframe src="http://127.0.0.1:3000/index2.html" frameborder="0"></iframe>
<script>
const iframe = document.querySelector("iframe");
iframe.onload = function () {
console.log(iframe)
// 獲取iframe的window對象
const iWindow = iframe.contentWindow;
// 獲取iframe的document對象
const iDocument = iframe.contentDocument;
console.log(iWindow)
console.log(iWindow.location)
iWindow.say()
iDocument.body.innerHTML = "<h1>this is html-1</h1>"
}
</script>
</body>
html2
<body>
<h1>html-2</h1>
<script>
function say() {
console.log("saying!!!")
}
</script>
</body>
效果圖
index1.html嵌套同源的index2.html
發(fā)現(xiàn)子iframe的window,document,location對象,以及子iframe的全局方法都可以訪問。

當(dāng)iframe與父窗口不同源時
- 父窗口無法訪問
iframe的window的所有屬性與方法。 - 父窗口無法訪問
iframe的document。 - 無法調(diào)用
iframe的全局方法。
效果圖


跨窗口通信
一:通過window.parent、frames、top
window.frames:獲取子iframe的列表,與document.querySelector("iframe")一樣
window.parent:獲取父window的引用
window.top:獲取最頂層窗口的window引用
上一節(jié)我們講到,當(dāng)iframe同源時,不同窗口可以拿到對方的window對象,以及全局方法,那么我們可以利用全局方法來實現(xiàn)不同window窗口的通信。
html1
<body>
<h1>html-1</h1>
<div>
<button onclick="send(Math.random(1))">發(fā)送數(shù)據(jù)給html2</button>
</div>
<iframe src="http://127.0.0.1:3000/index2.html" frameborder="0"></iframe>
<script>
const iframe = document.querySelector("iframe");
let send;
iframe.onload = function () {
// 獲取iframe的window對象
const iWindow = iframe.contentWindow;
// 獲取iframe的document對象
const iDocument = iframe.contentDocument;
function receive(value) {
console.log("這是html1,來了一條數(shù)據(jù):", value)
}
send = function (value) {
iWindow.receive(value)
}
}
</script>
</body>
html2
<body>
<h1>html-2</h1>
<div>
<button onclick="send(Math.random(1))">發(fā)送數(shù)據(jù)給html1</button>
</div>
<script>
function receive(value) {
console.log("當(dāng)前是html2,收到一條數(shù)據(jù):", value)
}
function send(value) {
window.parent.receive(value)
}
</script>
</body>
效果圖

同理,window.top也可以這樣通信
二:window.postMessage
postMessage支持不同窗口之間的通信,即使是非同源的情況。
發(fā)送數(shù)據(jù)
當(dāng)需要使用給其他窗口(window)發(fā)送數(shù)據(jù)時,需要調(diào)用對方window的postMessage方法。
該方法接收兩個參數(shù)
- 參數(shù)一:需要發(fā)送的數(shù)據(jù),數(shù)據(jù)最后為字符串形式,因為IE只支持字符串?dāng)?shù)據(jù)。
- 參數(shù)二:接收方的地址(協(xié)議+域名+端口)
接收數(shù)據(jù)
監(jiān)聽message事件
該事件對象包含接收的數(shù)據(jù),以及發(fā)送方的地址等信息。
html1
<body>
<h1>html-1</h1>
<div>
<button onclick="send(Math.random(1))">發(fā)送數(shù)據(jù)給html2</button>
</div>
<iframe src="http://127.0.0.1:3001/index2.html" frameborder="0"></iframe>
<script>
const iframe = document.querySelector("iframe");
let send;
iframe.onload = function () {
// 獲取iframe的window對象
const iWindow = iframe.contentWindow;
send = function (value) {
iWindow.postMessage("wuwuwuw", "http://127.0.0.1:3001")
}
}
window.addEventListener("message", function (event) {
if (event.origin != 'http://127.0.0.1:3001') {
// 過濾指定地址的信息
return;
}
if (window == event.source) {
// 頁面初始化的時候會被瀏覽器觸發(fā)一次message,在這里根據(jù)發(fā)送方地址進(jìn)行過濾
return
}
console.log("html1收到的數(shù)據(jù) " + event.data);
})
</script>
</body>
html2
<body>
<h1>html-2</h1>
<div>
<button onclick="send(Math.random(1))">發(fā)送數(shù)據(jù)給html1</button>
</div>
<script>
function receive(value) {
console.log("當(dāng)前是html2,收到一條數(shù)據(jù):", value)
}
function send(value) {
window.parent.postMessage(value, "http://127.0.0.1:3000")
}
window.addEventListener("message", function (event) {
if (event.origin != 'http://127.0.0.1:3000') {
// 過濾指定地址的信息
return;
}
if (window == event.source) {
// 頁面初始化的時候會被瀏覽器觸發(fā)一次message,在這里根據(jù)發(fā)送方地址進(jìn)行過濾
return;
}
console.log("html2收到的數(shù)據(jù) " + event.data);
})
</script>
</body>
效果圖

其他通信方法
- 使用soket,需要后端支持
- 使用本地存儲,監(jiān)聽本地存儲的數(shù)據(jù)變化
以上就是React常見跨窗口通信方式實例詳解的詳細(xì)內(nèi)容,更多關(guān)于React跨窗口通信方式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React?Native?加載H5頁面的實現(xiàn)方法
這篇文章主要介紹了React?Native?加載H5頁面的實現(xiàn)方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
基于react hooks,zarm組件庫配置開發(fā)h5表單頁面的實例代碼
這篇文章主要介紹了基于react hooks,zarm組件庫配置開發(fā)h5表單頁面,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
React利用路由實現(xiàn)登錄界面的跳轉(zhuǎn)
這篇文章主要介紹了React利用路由實現(xiàn)登錄界面的跳轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

