一.简介

window.postMessage is a method for safely enabling cross-origin communication. Normally, scripts on different pages are only allowed to access each other if and only if the pages which executed them are at locations with the same protocol (usually bothhttp), port number (80 being the default for http), and host (modulo document.domain being set by both pages to the same value).window.postMessage provides a controlled mechanism to circumvent this restriction in a way which is secure when properly used.

来源(https://developer.mozilla.org/en-US/docs/DOM/window.postMessage )

出于安全考虑,运行在同一浏览器中的框架、标签页、窗口间的通信都受到了严格的限制。通常,只有在协议(规则)、端口、主机完全相同的时候,也就是同源(origin)文档才可以通信,不同页面之间的脚本才能够相互访问。这个安全策略虽然防止恶意网站与其他内容交互,但是也让制作有多个数据来源的聚合应用(mashup)变得很困难。

为了满足这一需求,浏览器厂商和标准制定机构一直同意引入一种新功能:跨文档消息通信(Cross Document Messaging)。跨文档消息通信可以确保iframe、标签页、窗口间安全的进行跨源通信。window.postMessage 使跨源通信成为一种安全的方法。window.postMessage 通过安全可靠的方式实现了对这个限制的突破,很方便的实现了跨文档消息通信。跨文档消息通信是构建实时(real-time)跨源(cross-origin)通信的两个重要模块之一(另一个是XMLHttpRequest Level 2)。

源(origin)的概念:由规则(scheme)、主机(host)、端口构成(port)组成。由于规则不同(如https与http),所以https://www.123.com与http://www.123.com的源是不同的。而源不考虑路径,http://www.123.com/default.html与http://www.123.com/index.html 是同源的。当然window.postMessage不仅仅可以在跨源(cross-origin)通信中使用,在同源通信中也可以使用。

二.使用方法:

  1. 支持检测:版本比较旧的浏览器可能不支持window.postMessage,IE8以下的版本不支持。typeof(otherWindow .postMessage===undefined)

  2. 发送消息:otherWindow .postMessage(message ,targetOrigin );
    调用某个otherWindow 对象的postMessage()时,目标域名和该otherWindow 的域名一致,那么document的message事件则会被触发。也就是说otherWindow 是要接收消息的目标,是otherWindow 自己给自己发消息,只不过这个语句是在该otherWindow 的外部调用。

    otherWindow :目标对象的window。

    message:发送的消息。

    targetOrigin:目标对象的源。

    Note: Prior to Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the message parameter must be a string. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the message parameter is serialized using the structured clone algorithm. This means you can pass a broad variety of data objects safely to the destination window without having to serialize them yourself.

  3. 接收消息:用otherWindow 中的事件监听来监听消息。为该消息事件创建的Event对象包含以下属性:
    data:传递过来的消息,也就是postMessage函数中的第一个参数message。
    origin:发送该消息的源,otherWindow .postMessage(message ,targetOrigin );所在window的源
    source:发送该消息的窗口对象

三.例子:

定义两个不同的源分别用来发送消息和接收消息,部署在本地同一个服务器IIS中实现。将发布的绑定地址为127.0.0.1,但是要把端口设置不一样。

  1. http://post.com:8080 用来发送消息,发送的是一个时间秒数,每秒发送一次。

    <html>
    <head>
    <h2>PostMessage</h2>
    <p>http://post.com:8080</p>
    </head>
    <body>
    <input id="button" type="button" value="button" />
    <br />
    <script type="text/javascript">
    window.onload = function () {if (typeof window.postMessage === undefined) {//检测浏览器是否支持alert("unavailibale");} else {var button = document.getElementById("button");setInterval(function () {var date = new Date();var s = date.getSeconds();button.value = s;//传送消息,window.top 是当前窗口的顶级窗口,//是接收消息的窗口,而不是当前的窗口,发送的是一个时间的秒数window.top.postMessage(s, "http://receive.com:8081");}, 1000);}
    }
    </script>
    </body>
    </html>
  2. http://receive.com:8081/用来接收传来的消息,其中要在iframe中包含http://post.com:8080,代码如下:

    <html>
    <head>
    <h2>ReceiveMessage</h2>
    </head>
    <body>
    <p>http://receive.com:8081</p>
    <iframe id="iframe" src="http://post.com:8080/"></iframe>
    <br />
    <input id="message" type="text" />
    <script type="text/javascript">
    if (typeof window.postMessage === undefined) {alert("unavailibale");
    }
    else{function receiveMsg(e) {if (e.origin == "http://post.com:8080") {//只接收指定的源发来的消息var massage = document.getElementById("message");massage.value = e.data;};};window.addEventListener("message",receiveMsg,true);
    }
    </script>
    </body>
    </html>
    
  3. 最后,在C:\Windows\System32\drivers\etc找到hosts进行修改,加入如下两句

    127.0.0.1 receive.com
    127.0.0.1 post.com
    

运行结果如下:

访问:http://receive.com:8081/ 

H5跨域通信 - window.postMessage相关推荐

  1. html5跨域通信之postMessage

    html5跨域通信之postMessage的用法 不同域名下的文档因为安全问题,不允许相互之间文档的访问,但是有的时候却不得不需要这样的操作.因此我们一般可以采用 window.name,hash,或 ...

  2. window.postMessage - 前端跨域通信

    window.postMessage - 前端跨域通信 window.postMessage() 语法 The dispatched event 安全问题 示例 注意 HTMLIFrameElemen ...

  3. 使用window.postMessage实现跨域通信

    JavaScript由于同源策略的限制,跨域通信一直是棘手的问题.当然解决方案也有很多: document.domain+iframe的设置,应用于主域相同而子域不同: 利用iframe和locati ...

  4. ifrme嵌入外部页面,在外部页面调用本页面方法,window.postMessage实现跨域通信

    项目场景:vue页面开发的系统要继承外部系统页面,并且在外部系统页面调用本系统的方法,这样来看的话肯定会存在跨域的问题,而且直接调用方法的话,也不太安全,后来了解到window.postMessage ...

  5. 服务端转发html页面,html5关于外链嵌入页面通信问题(postMessage解决跨域通信)

    说起来挺简单的,可以直接去查询postMessage推送和window.addEventListener接收使用方式,能自己搞明白是最好的,本文章也只是记录一下自己的使用方式 使用postMessag ...

  6. vue页面内嵌iframe使用postMessage进行跨域通信

    跨域 关于跨域的详细资料:跨域,这里只需要明确什么情况下跨域了(等同于两个url什么情况下是非同源关系). 协议.域名.端口三者有其一不同,就算是跨域,就算是非同源 本地环境模拟 借助phpstudy ...

  7. 前端跨域通信的几种方式

    前言 前端通信类的问题,主要包括以下内容: 1.什么是同源策略及限制 同源策略是一个概念,就一句话.有什么限制,就三句话.能说出来即可. 2.前后端如何通信 如果你不准备,估计也就只能说出ajax. ...

  8. 【JavaScript】父子页面之间跨域通信的方法

    由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇"跨域,不再纠结&quo ...

  9. ios 跨域_如何在iOS和Android中建立跨域通信桥

    ios 跨域 I was working on a certain project at work, in which I needed to connect several varying comp ...

最新文章

  1. extjs video
  2. 建立数组并写入数据_redis高并发利器:神奇的位操作,底层原理、数据结构剖析...
  3. linux用head显示15字符,每天一个linux命令-head
  4. 在CLASSPATH中加载目录下所有的jar
  5. VA02修改销售订单的BAPI举例
  6. Python连接ActiveMQ的操作
  7. Go 使用 JSON
  8. 原生态mysql_mysql基础原生sql教程
  9. 使用JWT来实现单点登录功能
  10. 世界上没有一模一样的东西_免费是世界上最昂贵的东西
  11. sql_插入,修改,删除
  12. JDK 和 JRE 有什么区别
  13. 一个简单todos的例子
  14. JIRA带来的管理思路
  15. 如何利用家庭闲置宽带赚钱,甜糖 x86 docker 从零开始搭建
  16. fabric 中 peer 和 couch 容器中网络和数据存放目录地址
  17. 【数学】用C语言实现函数的定积分—— 把 “定积分定义计算出的值” 和 “牛顿-莱布尼兹公式计算出的值” 两者进行误差比较
  18. 如何获取iOS App素材
  19. Navicat Premium 连接oracle 提示ORA-01017:用户名/口令无效;登陆被拒绝
  20. C++的sort函数对于vector排序

热门文章

  1. 初中物理60个重要知识点
  2. Java实现打印功能
  3. Python编程从入门到实践---pygame精灵组
  4. 鼠眼看Linux调度器
  5. kd树 python实现_Python - KDTree 实现
  6. 前端必会的anime动画库
  7. 台式计算机外观组成部分,台式电脑由哪些部分组成?
  8. java模拟KTV点歌系统
  9. 山寨美图秀秀的美肤功能----实现过程
  10. 小学计算机应用到英语课教案,信息技术与小学英语教学有效融合(转载)