postMessage - 跨域消息传递

2023-10-28

window.postMessage() 方法允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本,而不用管是否跨域。一个文档里的脚本还是不能调用在其他文档里方法和读取属性,但他们可以用这种消息传递技术来实现安全的通信。

这项技术称为“跨文档消息传递”,又称为“窗口间消息传递”或者“跨域消息传递”。

postMessage() 方法,该方法允许有限的通信 —— 通过异步消息传递的方式 —— 在来自不同源的脚本之间。

postMessage 可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 页面与嵌套的 iframe 消息传递
  • 多窗口之间消息传递

想要使用 postMessage 实现跨域通信和页面间数据通信,只要记住 window 提供的 postMessage 方法和 message 事件就ok了。

一、语法

otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow

其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames。

message

要发送的数据。它将会被结构化克隆算法序列化,所以无需自己序列化(部分低版本浏览器只支持字符串,所以发送的数据最好用JSON.stringify() 序列化)。

targetOrigin

通过 targetOrigin 属性来指定哪些窗口能接收到消息事件,其值可以是字符串“*”(表示无限制)或者一个 URI(如果要指定和当前窗口同源的话可设置为"/")。在发送消息的时候,如果目标窗口的协议、主机地址或端口号这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会发送。

二、接收消息

如果指定的源匹配的话,那么当调用 postMessage() 方法的时候,在目标窗口的Window对象上就会触发一个 message 事件。

window.addEventListener("message", (event)=>{
   var origin = event.origin;
   // 通常,onmessage()事件处理程序应当首先检测其中的origin属性,忽略来自未知源的消息
   if (origin !== "http://example.org:8080")
     return;
   // ...
}, false);

event 的属性有:

  • data: 从其他 window 传递过来的数据副本。 
  • origin: 调用 postMessage 时,消息发送窗口的 origin。例如:“http://example.com:8080”。
  • source: 对发送消息的窗口对象的引用。可以使用此来在具有不同 origin 的两个窗口之间建立双向数据通信。 

三、使用场景

当想要在Web页面中嵌入一个来自其他站点的模块或者“gadget”的时候,利用 postMessage() 和 message 事件实现的跨域消息传递是很有用的。

首先 gadget 的开发者可以将 gadget 内容定义在一个 HTML 页面中,它负责监听 message 事件,并将它们分发给对应的 js 函数去处理。然后,嵌入 gadget 的Web页面就可以通过 postMessage() 方法传递消息来和 gadget 进行交互了。

四、完整示例

1. 不同 origin 的两个窗口之间建立双向数据通信

/**
* localhost:10002/index页面
**/
// 接收消息
window.addEventListener('message', (e) => {
     console.log(e.data)
})
// 发送消息
const targetWindow = window.open('http://localhost:10001/user');
setTimeout(()=>{
     targetWindow.postMessage('来自10002的消息', 'http://localhost:10001')
}, 3000)
/**
* localhost:10001/user页面
**/
window.addEventListener('message', (e) => {
     console.log(e.data)
     if (event.origin !== "http://localhost:10002") 
     return;
     e.source.postMessage('来自10001的消息', e.origin)
})

2. 页面与嵌套的 iframe 消息传递

http://www.domain1.com/a.html

<iframe id="iframe" src="http://www.domain2.com/b.html"></iframe>

<script>
var iframe = document.getElementById('iframe');

iframe.onload = function() {
   // 向domain2发送跨域数据
   iframe.contentWindow.postMessage('来自domain1的消息', 'http://www.domain2.com');
};

// 接受domain2返回数据
window.addEventListener('message',(e) => {
    console.log(e.data);
}, false);
</script>

http://www.domain2.com/b.html

<script>
// 接收domain1的数据
window.addEventListener('message',(e) => {
    console.log(e.data);

    if(e.origin !== 'http://www.domain1.com')
    return;

    // 发送消息给domain1
    window.parent.postMessage('来自domain2的消息', e.origin);
}, false);
</script>

五、安卓平台差异化处理

/* Android 平台 Post Message 消息监听 Hook */
window.Android_handleMessage = message => {
    // Android 使用 Base64 编码格式,需要先解码
    let data = decodeURIComponent(escape(window.atob(message)));
};

六、安全问题

  1. 如果你不希望从其他网站接收 message,请不要为 message 事件添加任何事件监听器。
  2. 如果你确实希望从其他网站接收message,请始终使用 origin 和 source 属性验证发件人的身份。
  3. 当你使用 postMessage 将数据发送到其他窗口时,始终指定精确的目标 origin,而不是 *。

七、兼容性

所有主流浏览器(包括IE8)都支持。

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

postMessage - 跨域消息传递 的相关文章

  • WebSocket协议深入理解

    1 WebSocket和HTTP的关系 WebSocket只有在建立握手连接的时候借用了HTTP协议的头 连接成功后的通信部分都是基于TCP的连接 总体来说 WebSocket协议是HTTP协议的升级版 2 研究WebSocket的思路 服
  • Uncaught SyntaxError: Unexpected end of input

    Uncaught SyntaxError Unexpected end of input 最近做项目遇到这样一个问题Uncaught SyntaxError Unexpected end of input Unexpected end of
  • 企业网上下单订货管理软件源码搭建功能介绍

    网上下单订货管理软件源码搭建功能介绍 订货通订单管理系统APP 一 系统概述和用途 系统基于网络 实现厂家和代理商批发商通过网络下单订货功能 什么是订货通 什么是企业订货管理系统 是一款针对中小型企业通过网络实现 厂家和客户 经销商 批发商
  • innerHTML与XSS攻击

    HTML5为所有元素提供了一个innerHTML属性 既能获取对象的内容又能向对象插入内容 属性值 HTML标签 文本 浏览器会将属性值解析为相应的DOM树 HTML解析器在浏览器中是底层代码比JavaScript方法快很多 同时意味着替换
  • css改变svg颜色_如何使用CSS混合模式和SVG动态更改产品图像的颜色

    css改变svg颜色 To better explain that title right off the bat here s what we re about to learn and it s easier than you thin
  • 【H5】 svg动画 旋转属性与虚线属性

    svg 动画 旋转 transform rotate angle x y 不要写在style里面 angle 旋转角度 x y旋转中心 绘制虚线 stroke dasharray a b a b c d 旋转属性 transform rot
  • 微信H5如何关闭浏览器(如何监听手机的物理返回键)

    一 背景 背景是这样的 该项目进入h5时会通过 location replace xxx 或 location href xxx 跳转到某个地址 该地址会请求获得微信 openId 获取成功后再重定向到h5首页 那么问题来了 重定向会在微信
  • html5自带属性验证表单必填

    html5自带属性验证表单必填 2014年02月25日 Html5 共 366字 字号 小 中 大 6条评论 阅读 6 515 次 为了防止恶意注册 通常会验证表单必填 实现方法以js为主 略微麻烦 今天才发现 html5如今已自带验证表单
  • 修改网页logo

    在用浏览器打开网站的时候 浏览器标签页上面有网站的图标 类似于logo小图标 如下图 步骤1 打开你的tomcat的安装目录 我的目录实在G盘 G apache tomcat 7 0 53 windows x64 apache tomcat
  • 基于vue-cli3模板的axios封装项目

    为了更便捷的使用项目框架 本模板为空白项目 但是已经为大家封装了axios方法和post get请求 内有基础案例 请大家按着自己项目需要进行修改使用 axios interceptors response use response gt
  • HTML学习

    HTML 我的第一个网页 基本标签 图片标签 链接标签 列表 表格 媒体元素 页面结构分析 iframe内联框架 表单 我的第一个网页
  • div标签的contenteditable属性实现input效果以及控制input的聚焦失焦

    在触屏 移动端网页 中 聊天室类型的输入框很常见 但是很多都是自定义样式的 直接改造input标签会很麻烦 给div标签设置contenteditable属性可以达到input标签的效果还能轻松的自定义样式 利用input事件和v text
  • 通过点击按钮在页面添加图片

    点击添加按钮 在盒子中加入图片 点击图片实现删除图片效果 代码如下
  • 大学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载 HTML5期末大作业 (1)

    HTML5期末大作业 动漫电影主题 电影动漫言叶之庭 4页 带音乐 HTML CSS JavaScript 期末作业HTML代码 学生网页课程设计期末作业下载 web网页设计制作成品 大学生毕设网页设计源码HTML 1 临近期末 你还在为H
  • 微信小程序:图片高度设置无效问题

    控制台查看元素 显示其style中多了一个没有设置的高度值 找了很久发现是因为image标签设置了mode widthFix 此时高度会自适应 样式中设置高度无效
  • 【H5】 svg画扇形饼图

    H5 svg画扇形饼图 效果图如下 封装代码如下 代码内有详细注解哦
  • 移动端适配-01-百分比宽度

    1 图片可以在parent中使用 1 line heigh和text align使水平和竖直居中 2 在img标签中加vertical align middle 2 3 background size 1 两个参数 background s
  • 【HTML】HTML5的拖放你用了吗

    HTML HTML5的拖放你用了吗 引言 github HTML HTML5的拖放你用了吗 内容速递 看了本文您能了解到的知识 在 HTML5 中 拖放是标准的一部分 任何元素都能够拖放 拖放的操作 多用在拖拽排序列表 游戏拼图等 下文中出
  • 三维实时重建BundleFusion

    转自 计算机视觉方向简介 深度相机室内实时稠密三维重建 知乎 室内场景的稠密三维重建目前是一个非常热的研究领域 其目的是使用消费级相机 本文特指深度相机 对室内场景进行扫描 自动生成一个精确完整的三维模型 这里所说的室内可以是一个区域 一个
  • 网页订货系统的诸多优势|企业APP订单管理软件

    1 订单信息 发货信息 账目信息一目了然 生产企业 总代理 和分销商之间可以清楚直观的了解到商品和货款的实时状态 以便高效的订货 发货 进行货款催收以及商品的物流跟踪 2 建立稳固的客户关系 避免客户被竞争对手挖墙脚 有了网上订货系统 企业

随机推荐

  • 2023.9.8 基于传输层协议 UDP 和 TCP 编写网络通信程序

    目录 UDP 基于 UDP 编写网络通信程序 服务器代码 客户端代码 TCP 基于 TCP 编写网络通信程序 服务器代码 客户端代码 IDEA 打开 支持多客户端模式 UDP 特点 无连接性 发送端和接收端不需要建立连接也可相互通信 且每个
  • 聊聊火出圈的ChatGPT

    前言 OpenAI 近期发布聊天机器人模型 ChatGPT 迅速火爆各大技术网站 就像一个突然激起的巨浪打破了沉寂已久的水面 它的出现无论是对人工智能的资本圈还是技术圈都感受到了春风回暖 前兔似锦的未来 尤记得2015年谷歌开源的Tenso
  • 机器人编程需要c语言吗,机器人编程和计算机编程有什么不一样

    原标题 机器人编程和计算机编程有什么不一样 格物斯坦小坦克就大家关心的机器人编程教育和计算机编程教育做一个对比 这样帮助大家更好地了解二者的共同性和区别 机器人编程的目的是让学生学会组装 搭建和编写程序运行机器人 课程的内容由硬件知识和编程
  • python中super的作用_Python代码中super()函数具有哪些功能呢?

    摘要 下文讲述Python代码中super 函数的功能说明 如下所示 super函数简介 super 函数是Python中的一个内置函数 用来处理多重继承问题中直接用类名调用父类方法 在使用单继承的时候没问题 当使用多继承 会涉及到查找顺序
  • 小米4A刷入breed教程

    已迁移到新的博客 新链接 飞young使用路由器教程 ndsx的博客 CSDN博客https blog csdn net qq 58617843 article details 127381367 csdn share tail 7B 22
  • Go 语言面试题(一):基础语法

    文章目录 Q1 和 的区别 Q2 指针的作用 Q3 Go 允许多个返回值吗 Q4 Go 有异常类型吗 Q5 什么是协程 Goroutine Q6 如何高效地拼接字符串 Q7 什么是 rune 类型 Q8 如何判断 map 中是否包含某个 k
  • Oracle中的序列(Sequence)

    1 什么是序列 序列 SEQUENCE 是序列号生成器 可以为表中的行自动生成序列号 产生一组等间隔的数值 类型为数字 不占用磁盘空间 占用内存 其主要用途是生成表的主键值 可以在插入语句中引用 也可以通过查询检查当前值 或使序列增至下一个
  • 入坑nodemcu,从刷固件到点亮LED,读完这篇文章就够了

    今天进手了一块nodemcu 准备入坑 有兴趣的朋友们 跟着小智手机手学习如何刷Lua固件且运行第一个亮灯实例吧 nodemcu NodeMCU 是一个开源的物联网平台 它包含了可以运行在esp8266 Wi FiSoC芯片之上的固件 以及
  • 一个C#操作Excel类,功能比较全

    using System using System Data using System Configuration using System Web using Microsoft Office Interop using Microsof
  • 【STM32】系统时钟RCC详解(超详细,超全面)

    RCC Reset and Clock Control 复位和时钟控制 在绝大部分MCU芯片中都包含复位和时钟控制模块 也是MCU重要的组成部分 相比于以前51单片机 现在STM32内部集成的时钟模块功能更加丰富 包含时钟选择 倍频 输出
  • Vue.js基础知识解析:Vue绑定

    文章目录 Vue绑定 类绑定 对象语法 数组语法 样式绑定 对象语法 数组语法 常见绑定 文本绑定 属性绑定 事件绑定 Vue绑定 Vue js 是一种流行的前端 JavaScript 框架 用于构建交互式的用户界面 在 Vue 中 有多种
  • 微信小程序.日期组件

    缘起 微信小程序官方提供的picker样式不好控制 跟其他样式不统一 也没法进行其他操作 不如自定义一个 使用 picker view封装为一个组件 代码现成 直接复制过去用吧 效果 组件代码 haiweidate wxml
  • msgpack c++的使用

    msgpack C 的使用 一 MessagePack 是什么 二 msgpack的使用 三 总结 一 MessagePack 是什么 MessagePack 是一种高效的二进制序列化格式 二 msgpack的使用 include
  • 安卓(Android)的原生系统真的那么好用吗

    定制系统有定制系统的优点 它一定更适合中国的大众用户 毕竟中国的大众用户甚至连微信调整一个功能都可能不会使用了 学习成本 这种东西能不要就不要 在 Android 9 0 之前也一定更适合中国的 Android 软件环境 原生 Androi
  • tomcat如何增大并发_【高并发】高并发环境下如何优化Tomcat性能?看完我懂了!...

    写在前面 Tomcat作为最常用的Java Web服务器 随着并发量越来越高 Tomcat的性能会急剧下降 那有没有什么方法来优化Tomcat在高并发环境下的性能呢 Tomcat运行模式 Tomcat的运行模式有3种 1 bio模式 默认的
  • Doxygen和VS助手配置代码注释模板

    Title FileNote Shortcut filenote Description 文件注释 Copyright c YEAR xx科技有限公司 http blog csdn net stelalala All rights rese
  • android ios通用OTG,被忽视的iOS13福利:OTG随心读写移动SSD

    被忽视的iOS13福利 OTG随心读写移动SSD 2019 09 22 15 58 14 11点赞 59收藏 29评论 iOS13带来了深色模式 HapticTouch等众多新功能 但很少有人提到OTG读取优盘 移动固态硬盘的新增特性 所需
  • MySQL视图详解

    今天继续给大家介绍MySQL相关知识 本文主要内容是MySQL视图 一 MySQL视图详解 MySQL引入了视图的概念 所谓视图 其实就是一张虚拟的数据表 该数据表与其他普通数据表一样 有列和属性 视图和普通的数据表唯一不同的是 视图中本身
  • Java定义一个队列Queue及操作

    定义一个队列 定义一个队列 Queue
  • postMessage - 跨域消息传递

    window postMessage 方法允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本 而不用管是否跨域 一个文档里的脚本还是不能调用在其他文档里方法和读取属性 但他们可以用这种消息传递技术来实现安全的通信 这项技术称为 跨文