平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题

1.页面和其打开的新窗口的数据传递

2.多窗口之间消息传递

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

4.上面三个问题的跨域数据传递

postMessage()

这些问题都有一些解决办法,但html5引入的message的API可以更方便、有效、安全的解决这些难题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

postMessage(data,origin)方法接受两个参数

1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。

2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

http://test.com/index.html

<div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;"><div id="color">Frame Color</div></div><div><iframe id="child" src="http://lsLib.com/lsLib.html"></iframe></div>

我们可以在http://test.com/index.html通过postMessage()方法向跨域的iframe页面http://lsLib.com/lsLib.html传递消息

window.οnlοad=function(){window.frames[0].postMessage('getcolor','http://lslib.com');}

接收消息

test.com上面的页面向lslib.com发送了消息,那么在lslib.com页面上如何接收消息呢,监听window的message事件就可以

http://lslib.com/lslib.html

window.addEventListener('message',function(e){if(e.source!=window.parent) return;var color=container.style.backgroundColor;window.parent.postMessage(color,'*');},false);

这样我们就可以接收任何窗口传递来的消息了,为了安全起见,我们利用这时候的MessageEvent对象判断了一下消息源,MessageEvent是一个这样的东东

有几个重要属性

  1. data:顾名思义,是传递来的message
  2. source:发送消息的窗口对象
  3. origin:发送消息窗口的源(协议+主机+端口号)

这样就可以接收跨域的消息了,我们还可以发送消息回去,方法类似

简单的demo

在这个例子中,左边的div会根据右边iframe内div颜色变化而变化

<!DOCTYPE html>2 <html>3 <head>4     <title>Post Message</title>5 </head>6 <body>7     <div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">8         <div id="color">Frame Color</div>9     </div>
10     <div>
11         <iframe id="child" src="http://lsLib.com/lsLib.html"></iframe>
12     </div>
13
14     <script type="text/javascript">
15
16         window.οnlοad=function(){17             window.frames[0].postMessage('getcolor','http://lslib.com');18}19
20         window.addEventListener('message',function(e){21             var color=e.data;22             document.getElementById('color').style.backgroundColor=color;23         },false);24     </script>
25 </body>
26 </html>

<!doctype html>2 <html>3     <head>4         <style type="text/css">5html,body{6                 height:100%;7margin:0px;8}9         </style>
10     </head>
11     <body style="height:100%;">
12         <div id="container" οnclick="changeColor();" style="widht:100%; height:100%; background-color:rgb(204, 102, 0);">
13click to change color14         </div>
15         <script type="text/javascript">
16             var container=document.getElementById('container');17
18             window.addEventListener('message',function(e){19                 if(e.source!=window.parent) return;20                 var color=container.style.backgroundColor;21                 window.parent.postMessage(color,'*');22             },false);23
24function changeColor () {25                 var color=container.style.backgroundColor;26                 if(color=='rgb(204, 102, 0)'){27                     color='rgb(204, 204, 0)';28                 }else{29                     color='rgb(204,102,0)';30}31                 container.style.backgroundColor=color;32                 window.parent.postMessage(color,'*');33}34         </script>
35     </body>
36 </html>复制代码在例子中页面加载的时候主页面向iframe发送’getColor‘ 请求(参数没实际用处)window.onload=function(){window.frames[0].postMessage('getcolor','http://lslib.com');}iframe接收消息,并把当前颜色发送给主页面呢window.addEventListener('message',function(e){if(e.source!=window.parent) return;var color=container.style.backgroundColor;window.parent.postMessage(color,'*');},false);主页面接收消息,更改自己div颜色window.addEventListener('message',function(e){var color=e.data;document.getElementById('color').style.backgroundColor=color;},false);当点击iframe事触发其变色方法,把最新颜色发送给主页面复制代码
function changeColor () {var color=container.style.backgroundColor;if(color=='rgb(204, 102, 0)'){color='rgb(204, 204, 0)';}else{color='rgb(204,102,0)';}container.style.backgroundColor=color;window.parent.postMessage(color,'*');}

主页面还是利用刚才监听message事件的程序处理自身变色

window.addEventListener('message',function(e){var color=e.data;document.getElementById('color').style.backgroundColor=color;},false);

最后

很简单的用法却解决了大问题,据说Facebook已经在使用了,而且这也是html5另一个API——web workers传递消息的方法,那么它的浏览器兼容性怎么样呢?所谓浏览器兼容性几乎变成了IE几开始支持的问题了。。。不过好消息是跟localStorage一样,IE8+都支持了,只不过有些浏览器的低版本(比如FireFox4.0)并不支持window.onmessage=function(){}这种写法,所以我么最好使用事件绑定的写法,为了兼容IE,也要判断是否支持addEventListener。

转载于:https://www.cnblogs.com/djdliu/p/5159617.html

html5 postMessage解决跨域、跨窗口消息传递相关推荐

  1. [转]html5: postMessage解决跨域和跨页面通信的问题

    [转]html5: postMessage解决跨域和跨页面通信的问题 参考文章: (1)[转]html5: postMessage解决跨域和跨页面通信的问题 (2)https://www.cnblog ...

  2. ie浏览器设置允许跨域_ieTester允许跨域浏览窗口和框架

    在用 ieTester 测试网页时,每次打开 ie6 总是不断的弹出 Allow sub-frames to navigate across different domains?,意思是是否允许跨域浏 ...

  3. C# -爬虫之WebBrowser跨域跨iframe获取网页源码

    前言:这里关键写用WebBrowser跨域跨iframe获取网页源码的部分,本意是要爬取全职高手的有声小说,这类网站特殊,网页上广告大堆,爬起来真麻烦,比如我爬取的网站的mp3源文件下载还需要秘钥的, ...

  4. html5 postMessage解决跨域、跨窗口消息传递 BY:色拉油啊油

    一些麻烦事儿 平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题 1.页面和其打开的新窗口的数据传递 2.多窗口之间消息传递 3.页面与嵌套的iframe消息传递 4. ...

  5. 什么是跨域 , 跨域问题如何解决?

    跨域问题是我们前端开发中经常会遇到的问题,遇到这样的问题,我们如何解决呢? 主要内容 错误原因分析 用CORS来解决 一.错误原因分析 1.get接口 2.点击按钮ajax发送请求 3.当我们在小黑窗 ...

  6. ext.ajax.request跨域,跨域Ajax访问header中 x-requested-with丢失

    前端调用后端接口,本域情况下,ajax方式调用,request header中包含x-requested-with信息. 跨域情况下,request header中不再包含x-requested-wi ...

  7. SSO单点登录跨域跨服务器

    单点登录系统总结 关于登录 一.登录 1.当用户点击登录的时候,把当前页面的url用参数传递到登录页面 2.用户成功登录,生成token,保存到redis中(service层),key为token,v ...

  8. 前端解决跨域的九种方法

    什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.资源跳转:A链接.重定向.表单提交 2.资源嵌入: <link>.<scr ...

  9. 什么是跨域及怎么解决跨域问题?

    什么是跨域? 这篇博文解释的挺清楚,我直接引用 什么是跨域?怎么解决跨域问题?_L瑜-CSDN博客_跨域是什么意思 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加 ...

最新文章

  1. 计算机组成原理-第二章 数据表示与运算
  2. linux下vsftp
  3. MATLAB实战系列(四十)-小波变换MATLAB图像融合
  4. 庖丁解牛TLD(三)——算法初始化
  5. Jmeter 的json Extractor
  6. [译] 如何用ps制作泼水字
  7. 统计学习方法c++实现之二 k近邻法
  8. Adobe Flash Player v26.0.0.126发布:请尽快更新
  9. Django报错异常django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without
  10. 18种证明公安部门不再开具应该找谁开
  11. 增强型绿植植被指数_植被指数计算方法
  12. 没有事业的女孩子很悲惨 - - - 一位老总的话!
  13. light动名词_英语语法(5)动名词
  14. Matlab学习篇之s-function
  15. 杀怪物(dfs)题解
  16. System.DllNotFoundException: Unable to load DLL 'XX.dll': 找不到指定的模块。 (Exception from HRESULT:
  17. Windows下通过注册表修改某个类型文件的默认打开方式和文件图标
  18. Keil5.15使用GCC编译器编译STM32工程
  19. java微信网页支付_java实现微信H5支付
  20. 实战 J2EE 开发购物网站 开发环境篇

热门文章

  1. cdrx4自动排版步骤_现在的大学生,都不会论文排版了
  2. domain,DNS,冗余,DNS劫持的大致原理
  3. Android性能优化之启动优化实战篇,最新整理
  4. python【数据结构与算法】判断两棵树是否相等
  5. 利用vgg预训练模型提取图像特征
  6. php margin参数,margin参数简单介绍_html/css_WEB-ITnose
  7. 怎么用爬虫筛选简历_Python爬虫面试简历
  8. java读取unicode文件_java怎么样将unicode解码读取?Java读取本地文件进行unicode解码...
  9. 网站与网址现在还有人没搞清二者之间的区别吗?
  10. php绕后,php函数处理,绕来绕去?