H5页面跨窗口通信之postMessage(iframe子页面向父页面发送信息)

本文介绍了一种H5页面与父页面之间的跨域通信方法,包括父页面如何向子页面发送消息及子页面如何向父页面发送消息。此外,还提供了一些注意事项,如确保消息在iframe加载完成后发送,并在监听message事件时检查消息来源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求背景

    最近在做H5项目时,遇到一个需求,公司所有的项目共用了一个防人机页面,当人机验证完成时需要把结果参数发送给调用它的父页面,APP端在使用验证页面时,结果是通过H5与APP交互方法传递的;但是H5引用这个页面时,只能通过iframe内嵌的方式来实现,这样在验证通过后就面临着iframe内嵌页面需要将验证结果发送给外部父页面,通知外部父页面做相应的处理;

实现方式

    1.父页面发送消息,子页面接受消息

        父页面:

<!-- a.index.html -->
<h1>父页面</h1>
<iframe id="iframe" src="http://b.index.com"></iframe>
const iFrame = document.getElementById('iframe')
<!-- 需要等到iframe中的子页面加载完成后才发送消息,否则子页面接收不到消息 -->
iFrame.onload = function(){
  <!-- iFrame.contentWindow获取到iframe的window对象 -->
  iFrame.contentWindow.postMessage('父页面发送的消息','http://b.index.com');
}

        子页面:

//有发送就有接收,与postMessage配套使用的就是message事件
window.addEventListener('message',e=>{
    <!-- 对消息来源origin做一下过滤,避免接收到非法域名的消息导致的xss攻击 -->
    if(e.origin==='http://a.index.com'){
        console.log(e.origin) //父页面URL,这里是http://a.index.com
        console.log(e.source) // 父页面window对象,全等于window.parent/window.top
        console.log(e.data)  //父页面发送的消息
    }
},false)

    2.子页面发送消息,父页面接受消息  

        子页面:

window.parent.postMessage('子页面发送的消息','http://a.index.com')

        父页面:

window.addEventListener('message',e=>{
    <!-- 对消息来源origin做一下过滤,避免接收到非法域名的消息导致的xss攻击 -->
    if(e.origin==='http://b.index.com'){
        console.log(e.origin) //子页面URL,这里是http://b.index.com
        console.log(e.source) // 子页面window对象,全等于iframe.contentWindow
        console.log(e.data) //子页面发送的消息
    }
},false)

注意:

  • window.postMessage中的window指的是你想发送跨域消息的那个窗口(你需要通信的目标窗口),而不是自身窗口的window
    • 父页面中:父页面向子页面发送跨域信息,window就是在父页面中嵌入的iframe指向的子页面的window,即:iFrame.contentWindow

    • 子页面中:子页面想父页面发送跨域信息,window就是父页面的window,在这里因为子页面是嵌入到父页面中的,对于子页面来讲,window就是top或者parent

  • 需要等到iframe中的子页面加载完成后才发送消息,否则子页面接收不到消息

  • 在监听message事件时需要判断一下消息来源origin

最后附送父页面检测到子页面发送的消息后,调用iframe子页面自刷新方法:

父页面:

window.addEventListener("message", e => {
      if (e.data && e.data.verifData) {
        //调用子页面自刷新
        e.source.location.reload(true)
      }
    }, false)

 

### H5iframe之间的页面通信方式 #### 同域通信H5页面iframe中的页面属于同一域名时,可以直接通过`window.parent`或`contentWindow`对象进行访问。例如,在父页面中可以通过以下方法调用iframe的内容: ```javascript // 获取iframe内的窗口对象 var iframe = document.getElementById('frame'); console.log(iframe.contentWindow.document.body.innerHTML); // 访问iframe内部HTML[^1] ``` 在iframe内部也可以通过`window.parent`访问外部页面的对象。 #### 跨域通信 对于不同域名的情况,可以采用`postMessage()` API 实现安全的跨域消息传递。以下是具体实现方式及其示例代码: ##### 父页面iframe发送数据 父页面可以通过`postMessage()`函数向嵌入的iframe发送消息: ```javascript var iframe = document.getElementById('frame'); iframe.onload = function () { var data = { key: 'value' }; iframe.contentWindow.postMessage(data, '*'); // '*'表示不限制目标源,实际应用建议指定确切的目标地址 }; ``` ##### iframe接收来自父页面的数据 在iframe所在的页面上监听`message`事件以捕获传来的信息: ```javascript window.addEventListener('message', function (event) { console.log(event.origin); // 输出消息来源网址 console.log(event.data); // 处理接收到的消息内容 }); ``` 同样地,iframe也能主动向其宿主页面发送消息,而宿主页则需设置相应的侦听器来处理这些输入。 --- ### 如何从浏览器URL中获取参数信息? JavaScript提供了多种途径解析查询字符串参数。一种常见做法是操作`location.search`属性并结合正则表达式提取键值对。下面展示了一个简单的例用于演示这一过程: ```javascript function getUrlParams(url) { let params = {}; url.replace(/[?&]+([^=&]+)=([^&]*)/gi, (_,key,value)=>params[key]=decodeURIComponent(value)); return params; } let paramObj = getUrlParams(window.location.href); for(let k in paramObj){ console.log(`${k}:${paramObj[k]}`)[^2]; } ``` 此脚本定义了一个辅助函数 `getUrlParams`, 它接受 URL 字符串作为输入,并返回包含所有GET请求参数名与其对应值得对象形式的结果集。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值