網(wǎng)站首頁 編程語言 正文
iframe
跨窗口通信就是在嵌套了iframe
的時候,實現(xiàn)iframe
與父窗口的通信。
什么是iframe
- 它是一個
html
標簽,它可以將一個網(wǎng)站作為一個dom
元素,嵌入到另一個網(wǎng)站中。 -
iframe
具有自己的window
與document
對象。
使用場景
- 比如公司開發(fā)了一個完整的網(wǎng)站,需要在另一個項目中去使用。比如直播功能,一些插件,這時候就可以使用
iframe
嵌入的方式。減少了重復開發(fā)的時間,需要修改界面的時候,也只需要修改一份代碼即可。 - 微應用,微應用也有很多是使用
iframe
來實現(xiàn)。
同源策略
當兩個網(wǎng)站同時滿足:同協(xié)議+同域名+同端口的時候。
當iframe與父窗口同源時
- 父窗口可以對
iframe
進行完全訪問,如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
的全局方法都可以訪問。
當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é)我們講到,當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("當前是html2,收到一條數(shù)據(jù):", value) } function send(value) { window.parent.receive(value) } </script> </body>
效果圖
同理,window.top也可以這樣通信
二:window.postMessage
postMessage
支持不同窗口之間的通信,即使是非同源的情況。
發(fā)送數(shù)據(jù)
當需要使用給其他窗口(window)發(fā)送數(shù)據(jù)時,需要調(diào)用對方window
的postMessage
方法。
該方法接收兩個參數(shù)
- 參數(shù)一:需要發(fā)送的數(shù)據(jù),數(shù)據(jù)最后為字符串形式,因為IE只支持字符串數(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ā)送方地址進行過濾 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("當前是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ā)送方地址進行過濾 return; } console.log("html2收到的數(shù)據(jù) " + event.data); }) </script> </body>
效果圖
其他通信方法
- 使用soket,需要后端支持
- 使用本地存儲,監(jiān)聽本地存儲的數(shù)據(jù)變化
原文鏈接:https://juejin.cn/post/7155037804102156296
相關(guān)推薦
- 2022-08-10 詳細聊一聊algorithm中的排序算法_C 語言
- 2022-10-05 淺談Qt信號槽與事件循環(huán)的關(guān)系_C 語言
- 2022-12-05 Python實現(xiàn)字符串模糊匹配方式_python
- 2022-07-12 strcpy、strncpy與memcpy的區(qū)別你了解嗎?
- 2022-06-10 ASP.NET?Core使用EF保存數(shù)據(jù)、級聯(lián)刪除和事務使用_實用技巧
- 2022-10-11 Filter過濾器和Listener監(jiān)聽器
- 2022-04-17 Unity實現(xiàn)簡單的多人聊天工具_C#教程
- 2022-05-13 ffmpeg+pyqt5簡單實現(xiàn)一個抽幀可視化小工具
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支