这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
大家好,我叫小杜杜,相信各位小伙伴对跨域
都了解一些,那么你知道跨源
吗?献给大家说一个标签,不知道有没有小伙伴用,那就是iframe标签,这个标签的作用是嵌套其他页面,而主页面和嵌套的页面要想通信,就是跨源通信~
跨源通信
跨源通信:通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain
设置为相同的值) 时,这两个脚本才能相互通信。
从广义上讲,一个窗口可以获得对另一个窗口的引用(比如 targetWindow = window.opener
),然后在窗口上调用 targetWindow.postMessage()
方法分发一个 MessageEvent
消息。接收消息的窗口可以根据需要自由处理此事件 (en-US)
而window.postMessage()
可以安全的实现跨源通信
postMessage 的语法
语法:otherWindow.postMessage(message, targetOrigin, [transfer]);
-
otherWindow: 其他窗口(目标窗口)的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames(如父窗口向内嵌的iframe窗口发送信息)
-
message :
信息内容
,低版本浏览器只支持字符串,高版本可以各种数据都行 -
targetOrigin :
目标窗口的源
,可以是字符串*表示无限制,或URI,需要协议端口号和主机都匹配才会发送 -
transfer:可选,是一串和message 同时传递的
Transferable
对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
兼容性
MessageEvent
MessageEvent: 是接口代表一段被目标对象接收的消息。
如:
window.addEventListener("message", function(MessageEvent){
var origin = event.origin || event.originalEvent.origin;
....
}, false);
四个属性:
- messag:类型
- data:window.postMessage的第一个参数
- origin:调用postMessage时页面的当前状态
- source:调用postMessage的窗口信息
示例
通过iframe嵌套父子窗口进行通信
- 父窗口
<!--我是父窗口-->
<div class="parent" >
<iframe src="子窗口链接" id="iframe"></iframe>
</div>
<script>
//监听子窗口信息
window.addEventListener('message',function(event){
...
})
//父窗口给子窗口发消息,
document.getElementByID('iframe').contentWindow.postMessage(msg,'子窗口源');
</script>
- 子窗口
<!--我是子窗口-->
<div class="child"></div>
<script>
//子窗口给父窗口发消息
try {//放到trycatch里面,解决有些手机卡住报错问题
window.top.postMessage(msg,'父窗口源');
//嵌套一层使用window.top(parent),多层window.frameElement
//使用top而不是window,top指向iframe最顶层窗口
} catch (error) {
}
//监听父窗口信息
window.addEventListener('message',function(event){
...
})
</script>
注意:
- 父窗口给子窗口发信息,需要用
iframe
的contentWindow属性作为调用主体 - 子窗口给父窗口发的信息需要使用window.top,多层iframe使用window.frameElement
End
个人认为iframe这个标签非常🤮,因为我人生中的第一个通宵就在这个标签上,建议能不用就不要用,因为这个确实很🤮,但你至少要了解下,方便以后多一种选择,喜欢的点个赞👍🏻支持下吧(● ̄(エ) ̄●)