博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跨域解决方案之HTML5 postMessage
阅读量:6950 次
发布时间:2019-06-27

本文共 4127 字,大约阅读时间需要 13 分钟。

问题场景:

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端口)和相同的主机(两个页面的  的值相同)。 在正确使用的情况下,window.postMessage 提供了一个受控的机制来安全地绕过这一限制。

window.postMessage, 调用时,挂起的脚本必须执行完成才会将  派遣至目标window (例如:如果一个事件处理程序调用了window.postMessage,剩余的事件处理程序就会挂起超时等).   有消息类型, 它被设置为第一个参数值提供给window.postMessage的data属性, 对应的window调用window.postMessage的时候,window.postMessage主文档的来源的origin属性被称为源属性,指哪个调用window.postMessage的窗口。 (事件的其他标准属性都存在与对应的预期值.)

语法:

otherWindow.postMessage(message, targetOrigin);
otherWindow 引用另外一个窗口,比如上面实例中的iframe,contentWindow 是iframe中的window对象。
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 
: */// Called sometime after postMessage is calledfunction 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 事件
    
Test Web worker

在客户端的 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());

 

 

 

转载于:https://www.cnblogs.com/hutuzhu/p/4661526.html

你可能感兴趣的文章
为什么区块链世界既需要计算机科学家也需要经济学家?
查看>>
区块链100讲:10分钟教会你深挖以太坊数据层
查看>>
Sony智慧耳机:不但能轻松叫智能耳机也能与Alexa对话
查看>>
中小企业改造系统适应秒杀的场景
查看>>
Atom 微信小程序文件代码高亮
查看>>
Android 8.0 startActivity 流程图
查看>>
react 中间件的应用
查看>>
leetcode 198. 打家劫舍
查看>>
星星之火,可以燎原|”分阶段“裂变带来1周1万+垂直户
查看>>
详解bind
查看>>
自学Javascript笔记
查看>>
bootstrap-table 实现表头合并以及结合bootstrap-table-tree-column实现树状结构
查看>>
欢迎使用Markdown编辑器
查看>>
C语言调用python源码
查看>>
砥砺前行 | 2018 与我的技术之路
查看>>
重读vue的MVVM
查看>>
(转)iOS 某个界面支持旋转
查看>>
纯属个人瞎编乱造
查看>>
Git协作注意合并和衍合的区别,just避雷
查看>>
React + Antd 所遇问题
查看>>