HTML5 postMessage
2015-07-23 14:19
525 查看
问题场景:
web是嵌入到手机客户端中的静态页面,为了统计用户行为需要引入ga,但是ga必须是在www下才行,哪怕是localhost,这就是矛盾。解决方案是在页面中使用iframe,iframe是在另外一个域名下的,然后在iframe中调用ga方法。很显然必须要解决iframe的跨域通信。
每次点击指定区域时候向iframe中发送消息,然后在iframe中监听消息数据,发送ga。
好,实际场景和方法介绍完了,开工学习相关知识。
window.postMessage
在正确使用的情况下,
MessageEvent 有消息类型, 它被设置为第一个参数值提供给
语法:
[/code]
data:来自其他window的数据。
origin:调用postMessage的窗口url。
source:发送消息窗口的引用。可以使用该方法使来自不同源的窗口进行双向通信。
安全性
在web worker是中使用postMessage和onMessage
主线程中创建 Worker 实例,并监听 onmessage 事件
在客户端的 compute.js 中,只是简单的重复多次加和操作,最后通过 postMessage 方法把结果返回给主线程,目的就是等待一段时间。而在这段时间内,主线程不应该被阻塞,用户可以通过拖拽浏览器,变大缩小浏览器窗口等操作测试这一现象。这个非阻塞主线程的结果就是 Web Workers 想达到的目的。
compute.js 中调用 postMessage 方法返回计算结果
web是嵌入到手机客户端中的静态页面,为了统计用户行为需要引入ga,但是ga必须是在www下才行,哪怕是localhost,这就是矛盾。解决方案是在页面中使用iframe,iframe是在另外一个域名下的,然后在iframe中调用ga方法。很显然必须要解决iframe的跨域通信。
var frame=document.getElementById("gaFrame"); document.body.onclick=function(){ var sendData={ "name":"deals_list", "event":"deals_click", "e_data":"这是发送的数据" } frame.contentWindow.postMessage(sendData,"*") }
每次点击指定区域时候向iframe中发送消息,然后在iframe中监听消息数据,发送ga。
var OnMessage = function(e) { var data=e.data; ga('send', 'pageview',"/"+data); } function init() { if (window.addEventListener) { // all browsers except IE before version 9 window.addEventListener("message", OnMessage, false); } else { if (window.attachEvent) { // IE before version 9 window.attachEvent("onmessage", OnMessage); } } }; init();
好,实际场景和方法介绍完了,开工学习相关知识。
window.postMessage
window.postMessage是一个用于安全的使用跨源通信的方法。通常,不同页面上的脚本只在这种情况下被允许互相访问,当且仅当执行它们的页面所处的位置使用相同的协议(通常都是 http)、相同的端口(http默认使用80端口)和相同的主机(两个页面的 document.domain 的值相同)。
在正确使用的情况下,
window.postMessage提供了一个受控的机制来安全地绕过这一限制。
window.postMessage, 调用时,挂起的脚本必须执行完成才会将 MessageEvent 派遣至目标window (例如:如果一个事件处理程序调用了window.postMessage,剩余的事件处理程序就会挂起超时等).
MessageEvent 有消息类型, 它被设置为第一个参数值提供给
window.postMessage的data属性,对应的window调用window.postMessage的时候,window.postMessage主文档的来源的origin属性被称为源属性,指哪个调用window.postMessage的窗口。 (事件的其他标准属性都存在与对应的预期值.)
语法:
otherWindow.postMessage(message, targetOrigin);
otherWindow 引用另外一个窗口,比如上面实例中的iframe,[code]contentWindow是iframe中的window对象。
[/code]
message 发送到其他window中的数据 targetOrigin 目标源,可以限定只接收来自某个URL下的数据 监听发送事件
window.addEventListener("message", receiveMessage, false); function receiveMessage(event) { if (event.origin !== "http://example.org:8080") return; // ... }
data:来自其他window的数据。
origin:调用postMessage的窗口url。
source:发送消息窗口的引用。可以使用该方法使来自不同源的窗口进行双向通信。
安全性
var popup = window.open(...popup details...); // When the popup has fully loaded, if not blocked by a popup blocker: // This does nothing, assuming the window hasn't changed its location. popup.postMessage("The user is 'bob' and the password is 'secret'", "https://secure.example.net"); // This will successfully queue a message to be sent to the popup, assuming // the window hasn't changed its location. popup.postMessage("hello there!", "http://example.org"); function receiveMessage(event) { // Do we trust the sender of this message? (might be // different from what we originally opened, for example). if (event.origin !== "http://example.org") return; // event.source is popup // event.data is "hi there yourself! the secret response is: rheeeeet!" } window.addEventListener("message", receiveMessage, false);
/* * In the popup's scripts, running on <http://example.org>: */ // Called sometime after postMessage is called function receiveMessage(event) { // Do we trust the sender of this message? if (event.origin !== "http://example.com:8080") return; // event.source is window.opener // event.data is "hello there!" // Assuming you've verified the origin of the received message (which // you must do in any case), a convenient idiom for replying to a // message is to call postMessage on event.source and provide // event.origin as the targetOrigin. event.source.postMessage("hi there yourself! the secret response " + "is: rheeeeet!", event.origin); } window.addEventListener("message", receiveMessage, false);
在web worker是中使用postMessage和onMessage
主线程中创建 Worker 实例,并监听 onmessage 事件
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Test Web worker</title> <script type="text/JavaScript"> function init(){ var worker = new Worker('compute.js'); //event 参数中有 data 属性,就是子线程中返回的结果数据 worker.onmessage= function (event) { // 把子线程返回的结果添加到 div 上 document.getElementById("result").innerHTML += event.data+"<br/>"; }; } </script> </head> <body onload="init()"> <div id="result"></div> </body> </html>
在客户端的 compute.js 中,只是简单的重复多次加和操作,最后通过 postMessage 方法把结果返回给主线程,目的就是等待一段时间。而在这段时间内,主线程不应该被阻塞,用户可以通过拖拽浏览器,变大缩小浏览器窗口等操作测试这一现象。这个非阻塞主线程的结果就是 Web Workers 想达到的目的。
compute.js 中调用 postMessage 方法返回计算结果
var i=0; function timedCount(){ for(var j=0,sum=0;j<100;j++){ for(var i=0;i<100000000;i++){ sum+=i; } } // 调用 postMessage 向主线程发送消息 postMessage(sum); } postMessage("Before computing,"+new Date()); timedCount(); postMessage("After computing,"+new Date());
相关文章推荐
- HTML5中在客户端验证文件上传的大小
- 原生js结合html5制作小飞龙的简易跳球
- 三个不常见的 HTML5 实用新特性简介
- 低版本IE正常运行HTML5+CSS3网站的3种解决方案
- js+HTML5实现canvas多种颜色渐变效果的方法
- HTML5实现微信拍摄上传照片功能
- 2014 HTML5/CSS3热门动画特效TOP10
- HTML5使用DeviceOrientation实现摇一摇功能
- spring+html5实现安全传输随机数字密码键盘
- html5在android中的使用问题及技巧解读
- 非html5实现js版弹球游戏示例代码
- html5 canvas js(数字时钟)实例代码
- js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
- Jquery结合HTML5实现文件上传
- 使用js检测浏览器是否支持html5中的video标签的方法
- 如何使用HTML5地理位置定位功能
- 通过javascript把图片转化为字符画
- 使用PHP和HTML5 FormData实现无刷新文件上传教程
- 解决node-webkit 不支持html5播放mp4视频的方法