HTML5的postMessage使用记要////////////////////////////zzzzzzzz
HTML5提出了一个新的用来跨域传值的方法,即postMessage(这个名字太通俗了所以你最好看看是不是自己写过一个同名的把它覆盖了)。幸运的是IE8就开始支持了。
我们假设有两个网站,1.com与2.com,我在1.com的页面上通过iframe或window.open或超链接打开了一个2.com的网页,此时我要在2.com上做操作的时候,给1.com传值,让1.com有所变化。这个过程就是个跨域的过程。
如果你对window.open熟,你就会知道通过window.open打开的网页(我们称之为子网页),可以通过window.opener对象,访问到把它打开的页面(父网页),这样一来,调用父页面的函数就是非常简单的事了。但是,在跨域的条件下,window.opener就成了一个空对象,“没有权限”,浏览器会这么告诉你。
比如,你的父页面有个函数叫callback,然后你子页面本可以这样调用:window.opener.callback(),同域时能成功,跨域时就没有权限了。
但是,此时你调用window.opener.postMessage(),却可以成功!
关于跨域传值的痛苦我就不多说了,本文只说一些前两天学习postMessage时了解到的重要知识点。
postMessage语法
|
window.postMessage(msg,targetOrigin) |
这里我要专门说一下postMessage要通过window对象调用!因为这里的window不只是当前window,大部分使用postMessage的时候,都不是本页面的window,而是其他网页的window!如:
1,iframe的contentWindow
2,通过window.open方法打开的新窗口的window
3,window.opener
如果你使用postMessage时没有带window,那么,当然,你就是用的本页面的window来调用了它。
参数说明
msg
这就是要传递的消息了。它可以是一切javascript参数,如字符串,数字,对象,数组,而不是和json一样只局限于字符串,很强大吧?
targetOrigin
这个参数称作“目标域”,注意啦,是目标域不是本域!比如,你想在2.com的网页上往1.com网页上传消息,那么这个参数就是“http://1.com/”,而不是2.com.
另外,一个完整的域包括:
协议,主机名,端口号。如:http://g.cn:80/
获取postMessage传过来的消息
要对postMessage传来的消息进行处理,就要在页面上加一个onmessage事件。如:
|
1 2 3 4 |
window.addEventListener('message',function(e) { console.log(e.origin,e.data) ; alert('有数据传来了!') ; } ) |
要注意:最好是通过addEventListener或attachEvent来加入onmessage事件,而不要直接window.onmessage=function(){},因为有的浏览器这样加会识别不了(如低版Firefox)
这个onmessage事件接受一个参数,就是代码里的e,实际上他就是一个event对象。但他里面有很明显的3个参数与其他event对象不一样,即:
1,data:顾名思义,是传递来的message
2,source:发送消息的窗口对象
3,origin:发送消息窗口的源(协议+主机+端口号).比如从2.com往1.com发了消息,那么1.com收到消息时,e.origin就是2.com
最重要的就是data了,你可以用e.data取得他,然后做后续操作了。不过为了安全,你最好先判断一下e.source和e.origin是不是正确来源,再作操作。
完整的postMessage流程示例
接着刚才的例子来,我着重讲一个弹窗给父页面传消息的例子。
我们的父页面叫1.com,他上面有关键代码是:
|
1 2 3 4 |
window.addEventListener('message',function(e) { console.log(e.origin,e.data) ; alert('子页面有数据传来了!') ; } ) |
就这么简单。而弹出窗口(2.com)上的代码是:
|
1 2 |
vardomain='http://1.com/' ; window.opener.postMessage({obj:'I am a obj'}, domain ) |
还是很简单吧!你看,跨域时本来不能访问的window.opener可以访问了——不过你直接调用父页面的方法还是会失败!就是这么不讲理。
其他应用场景的例子
1,必须要说明:通过超链接打开的新窗口也能用window.opener来访问其父页面,代码跟上面一样
2,iframe的例子
父页面:
|
1 2 |
varo=document.getElementsByTagName('iframe')[0] ; o.contentWindow.postMessage('Hello World',"*"); //向框架页传消息 |
被框架包裹的子页面:
|
1 2 3 4 5 6 7 8 9 |
window.addEventListener('onmessage',function(e) { if(e.domain=='1.com') { if(e.data=='Hello World') { e.source.postMessage('Hello',"*"); //反过来向父页面传消息 }else { alert(e.data) ; } } }) ; |
这个例子充分说明了postMessage是双向的。
3,window.open一个窗口,然后向他传消息
父页面:
|
1 2 3 4 5 |
vardomain2='http://2.com/' ; varwin=window.open(domain2+'Portal/2.com.html','wwwwwwww' ) setTimeout(function() { win.postMessage('ddddddddd',domain2 ) },2000 ) |
子页面:
|
1 2 3 |
window.addEventListener('message',function(e) { console.log(e.origin,e.data ) } ) |
要注意父页面中的setTimeout,也就是要延迟传消息,因为子页面不可能瞬间加载完成,他的onmessage事件也就没初始化成功,这时给他传消息,当然是收不到的了。
后记
1,IE8+虽然支持postMessage,但只支持iframe的方式,window.open打开的新窗口之间,没法用。直到IE10才有相关改进
2,如何在本地模拟跨域呢?在hosts文件里加入:
127.0.0.1 1.com127.0.0.1 2.com
就可以模拟出2个不同的域名了。
参照信息:
HTML5 postMessage 和 onmessage API 详细应用
http://msdn.microsoft.com/en-us/library/ie/cc197015(v=vs.85).aspx
http://stackoverflow.com/questions/16226924/is-cross-origin-postmessage-broken-in-ie10
https://developer.mozilla.org/zh-CN/docs/Web/API/Window.postMessage
HTML5的postMessage使用记要////////////////////////////zzzzzzzz的更多相关文章
- HTML5的postMessage使用记要
HTML5提出了一个新的用来跨域传值的方法,即postMessage(这个名字太通俗了所以你最好看看是不是自己写过一个同名的把它覆盖了).幸运的是IE8就开始支持了. 我们假设有两个网站,1.com与 ...
- 通过Html5的postMessage和onMessage方法实现跨域跨文档请求访问
在项目中有应用到不同的子项目,通过不同的二级域名实现相互调用功能.其中一个功能是将播放器作为单独的二级域名的请求接口,其他项目必须根据该二级域名调用播放器.最近需要实现视频播放完毕后的事件触发,调用父 ...
- html5的postmessage实现js前端跨域訪问及调用解决方式
关于跨域訪问.使用JSONP的方法.我前面已经demo过了.详细见http://supercharles888.blog.51cto.com/609344/856886,HTML5提供了一个很强大的A ...
- 使用HTML5中postMessage实现Ajax中的POST跨域问题
HTML5中提供了在网页文档之间相互接收与发送信息的功能.使用这个功能,只要获取到网页所在窗口对象的实例,不仅仅同源(域+端口号)的web网页之间可以互相通信,甚至可以实现跨域通信. 浏览器支持程度: ...
- 使用HTML5中postMessage 实现ajax中的POST跨域问题
HTML5中提供了在网页文档之间相互接收与发送信息的功能.使用这个功能,只要获取到网页所在窗口对象的实例,不仅仅同源(域+端口号)的web网页之间可以互相通信,甚至可以实现跨域通信. 浏览器支持程度: ...
- html5 window.postMessage 传递数据的使用
window.postMessage(图片介绍): 发送方(图片介绍): 接收方(图片介绍): 个人测试一(iframe): 发送方,地址为:http://localhost:63342/HelloH ...
- HTML5 postMessage 跨域交换数据
前言 之前简单讲解了利用script标签(jsonp)以及iframe标签(window.name.location.hash)来跨域交换数据,今天我们来学习一下HTML5的api,利用postMes ...
- 利用HTML5的window.postMessage实现跨域通信
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp77 HTML5的window.postMessage简述 postM ...
- 跨域问题实践总结!下( [HTML5] postMessage+服务器端(反向代理服务器+CORS Cross-Origin Resource Sharing))
4. [HTML5] postMessage 问题: 对于跨域问题,研究了一下html5的postMessage,写了代码测试了一下,感觉html5新功能就是好用啊.此文仅使用html5的新特性pos ...
随机推荐
- 【改】iOS学习之NSAttributedString(富文本)
NSAttributedString 叫做富文本,是一种带有属性的字符串,通过它可以轻松的在一个字符串中表现出多种字体.字号.字体大小等各不相同的风格,还可以对段落进行格式化,一般都是对可变富文本(N ...
- WSDL项目---处理消息
有几个视图选择在处理SOAP请求和响应消息. 让我们看看这两个. 请求消息 XML ——标准的底层XML消息的文本视图Validate选项验证当前的消息发现的错误: (这里行号一直在编辑器中打开) ...
- 【Unity3d游戏开发】Unity3D中的3D数学基础---向量
向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3 ...
- Employment Planning[HDU1158]
Employment Planning Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- SPX Instant Screen Capture
Today I will recommend a NICE screen capture tool, which name is SPA Instant Screen Capture. http:// ...
- 在docker 中配置hadoop1.2.1 cluser
最近一直在找工作,比较空闲,就没事研究一下hadoop,网上的视频及书,讲的差不多都是1.2.1这个版本,然后就试着在docker中搭建了一个hadoop集群, 项目已经放到了github上面了,供新 ...
- 后台发送POST,DELETE,GET,PUT请求
public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, int> para ...
- table首行固定
转自http://www.cnblogs.com/azhqiang/p/3965774.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...
- 下载php扩展笔记
查找相关php的扩展网址https://pecl.php.net/index.php PECL 的全称是 The PHP Extension Community Library ,即PHP 扩展库.是 ...
- log4j.properties 使用
一.参数意义说明 输出级别的种类 ERROR.WARN.INFO.DEBUG ERROR 为严重错误 主要是程序的错误 WARN 为一般警告,比如session丢失 INFO 为一般要显示的信息,比如 ...