目标功能:
页面一跨域open页面二,页面二通过addEventListener监听到消息后,返回确认信息。页面一通过addEventListener监听页面二发送的确认信息后,将数据包发送给页面二。页面二获取数据包后进行处理。
postMessage简介(摘抄自他人博客,如涉抄袭,请联系我):
HTML5提出了一个新的用来跨域传值的方法,即postMessage。我们假设有两个网站,1.com与2.com,我在1.com的页面上通过iframe或window.open或超链接打开了一个2.com的网页,此时我要在2.com上做操作的时候,给1.com传值,让1.com有所变化。这个过程就是个跨域的过程。
如果你对window.open熟,你就会知道通过window.open打开的网页(我们称之为子网页),可以通过window.opener对象,访问到把它打开的页面(父网页),这样一来,调用父页面的函数就是非常简单的事了。但是,在跨域的条件下,window.opener就成了一个空对象,“没有权限”,浏览器会这么告诉你。
比如,你的父页面有个函数叫callback,然后你子页面本可以这样调用:window.opener.callback(),同域时能成功,跨域时就没有权限了。但是,此时你调用window.opener.postMessage(),却可以成功!
postMessage参数:postMessage(message, targetOrigin, [transfer])
message:
将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
message的三个属性:
data : 从其他 window 中传递过来的对象。
origin : 调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。例如 “https://example.org (implying port 443)”、“http://example.net (implying port 80)”、“http://example.com:8080”。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。
source :对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。
targetOrigin:
通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串”“(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的orign属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer (可选参数)
是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
例程:google和百度进行通信
页面一
window.open("www.baidu.com");
页面二
window.addEventListener('message', (e) => {
const data = e.data;
if (e.origin.includes('google.com") ) {
e.source.postMessage("我是百度,谷歌我收到你的消息了”,“www.google.com");
}
});
页面一
window.addEventListener('message', (e) => {
const data = e.data;
if (e.origin.includes('baidu.com") ) {
e.source.postMessage("我是谷歌,我知道百度收到了我的消息”,“www.baidu.com");
}
});
由此页面一二可进行数据的通信
addEventListener简介:addEventListener() 方法用于向指定元素添加事件句柄。
addEventListener三个参数:
element.addEventListener(event, function, useCapture)
参数描述
{
event(必须):字符串,指定事件名。
注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。
提示: 所有 HTML DOM 事件,可以查看我们完整的https://www.runoob.com/jsref/dom-obj-event.html。
function(必须):指定要事件触发时执行的函数。
当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。
useCapture(可选):布尔值,指定事件是否在捕获或冒泡阶段执行。
可能值:
true - 事件句柄在捕获阶段执行
false- false- 默认。事件句柄在冒泡阶段执行
}
例程:
function addAndRemove(){
console.log('add');
}
addEventListener('click',addAndRemove,false);
removeEventListener('click',addAndRemove,false);
addEventListener后需要remove以防止占用过多内存
removeEventListener时必须和addEvent的时指向同一个对象!
以下情况会生成不同的对象,导致remove失效
「
1、window.addEventListener('message', (e) => {})多次调用会多次生成不同的匿名函数e,应指向同一个命名函数
2、window.addEventListener('message', this.handler.bind(this)),命名函数绑定this后,调用会生成不同的对象
」