一、postMessage

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机(两个页面的模数 Document.domain设置为相同的值)时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

调用 postMessage() 方法时,向目标窗口派发一个 Event 消息。 该 Event 消息的 data 属性为 postMessage() 的数据;origin 属性表示调用 postMessage() 方法的页面的地址。

二、语法

otherWindow.postMessage(message, targetOrigin)

说明

  • otherWindow:其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames。
  • message:将要发送到其他 window 的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
  • targetOrigin:通过窗口的 origin 属性来指定哪些窗口能接收到消息事件,其值可以是字符串 * (表示无限制)或者一个 URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。

三、示例

我配了两个域名 example.mazey.cnexample0.mazey.cn,其中 http://example0.mazey.cn/post-message/send.html 会给 http://example.mazey.cn/post-message/receive.html 发送一条消息 Message From Mazey.

send.html

<script>
window.onload = function () {
window.parent.postMessage(
'Message From Mazey.',
'*'
)
}
</script>

receive.html

<script>
// 监听
window.addEventListener(
'message',
event => {
let origin = event.origin || event.originalEvent.origin
console.log(event, origin, event.data) // MessageEvent{...} "http://example0.mazey.cn" "Message From Mazey."
}
)
// 使用 JS 加载 iframe,保证监听创建后再加载 iframe。
let iframeEle = document.createElement('iframe')
iframeEle.src = 'http://example0.mazey.cn/post-message/send.html'
iframeEle.style = 'border: none;width: 0;height: 0;'
document.body.insertBefore(iframeEle, document.body.firstChild)
</script>

注意

如果发送的消息有敏感信息(例如:密码),始终验证接受时的 event.origin 和指定发送时的 targetOrigin。

使用 postMessage + iframe 实现跨域通信的更多相关文章

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

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

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

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

  3. HTML5:使用postMessage实现Ajax跨域请求

    HTML5:使用postMessage实现Ajax跨域请求 由于同源策略的限制,Javascript存在跨域通信的问题,典型的跨域问题有iframe与父级的通信等. 常规的几种解决方法: (1) do ...

  4. html5 postMessage解决iframe跨协议跨域通信问题

    a.html有个iframe载入b.com/login.html,当login完成时通知a.html页面登录完成并传递UserName 1.a.html 监听消息 window.addEventLis ...

  5. Javascript使用postMessage对iframe跨域通信

    今天才发现原来有这么个好东西啊,跨域通信太方便了, 举个小栗子: 共两个页面, 页面1:www.a.com/a.html 页面2:www.b.com/b.html 实现目标:两个网站页面实现跨域相互通 ...

  6. 使用 iframe + postMessage 实现跨域通信

    在实际项目开发中可能会碰到在 a.com 页面中嵌套 b.com 页面,这时第一反应是使用 iframe,但是产品又提出在 a.com 中操作,b.com 中进行显示,或者相反. 1.postMess ...

  7. JavaScript 跨域:window.postMessage 实现跨域通信

    JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...

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

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

  9. iframe跨域通信方案

    概述 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首先什么 ...

随机推荐

  1. hdoj 1272 小希的迷宫 又一个并查集的简单应用

    小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  2. 成为 Team Leader 后我最关心的那些事

    成为 Team Leader 后我最关心的那些事   推荐序 老有人问我 iOS 开发如何提高,今天收到一个来自网易的朋友投稿,分享他在成为 iOS 项目负责人之后面临的问题.文章中分享的如何招人,如 ...

  3. jquery衬衣产品内容详情页

    html代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  4. beans.xml的用法

    beans.xml <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="ht ...

  5. 解决将Ubuntu下导出的requirements.txt到Centos服务器上面出现pkg-resource的版本为0.0.0

    最直接有效的方法: 原因:

  6. DelphiXE8FMX工程实现无边框托动(FMX内部方法)

    注意: 可以实现效果,但不知道我的用法对不对(或着说是不是最优化的用法),望高手们指教. 实例代码: unit Unit1; interface uses System.SysUtils, Syste ...

  7. PHP——自定义函数

    <?php //定义有默认值的函数 function Main3($f=5,$g=6) { echo $f*$g; } Main3(2,3); echo "<br />&q ...

  8. oozie4.3.0+sqoop1.4.6实现mysql到hive的增量抽取

    1.准备数据源 mysql中表bigdata,数据如下: 2. 准备目标表 目标表存放hive中数据库dw_stg表bigdata 保存路径为 hdfs://localhost:9000/user/h ...

  9. go hmac使用

    https://github.com/danharper/hmac-examples 94 func generateSign(data, key []byte) string { 95 mac := ...

  10. C++ 匿名对象产生场景

    //匿名对象产生的三种场景 #include<iostream> using namespace std; class Point{ public: Point(int a,int b){ ...