GVKun编程网logo

html5 postMessage前端跨域并前端监听的方法示例(前端post解决跨域的方法)

8

关于html5postMessage前端跨域并前端监听的方法示例和前端post解决跨域的方法的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于HTML5postMessage和onmessa

关于html5 postMessage前端跨域并前端监听的方法示例前端post解决跨域的方法的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于HTML5 postMessage 和 onmessage API 详细应用、HTML5 postMessage 消息传输与 POST 跨域通信、HTML5 postMessage 跨域交换数据、HTML5 postMessage 跨域跨窗口传递消息等相关知识的信息别忘了在本站进行查找喔。

本文目录一览:

html5 postMessage前端跨域并前端监听的方法示例(前端post解决跨域的方法)

html5 postMessage前端跨域并前端监听的方法示例(前端post解决跨域的方法)

有时候会遇到傻X需求,比如前端单点登陆!遇到需求,就要去想解决办法, 这里我给大家做一个简单的前端单点登陆的解决方案, 用到的就是postMessage跨域信息传输以及onstorage的监听。 本文用到的知识点 koa架设静态资源服务、跨域、postMessage的用法、onstorage监听storage 第一步、架设两个不同端口的服务 我们这里用koa2来搭建两个服务到不同的端口,来模拟一下真正的工作中需要出现的跨域情况。 非常的简单 主要用到 koa-static这个中间件 搭建起来也是非常容易的,如果大家想学node相关的知识 可以加我微信shouzi_1994 或者在博客下面留言你的联系方式 这里就不多说废话了 直接上代码 视频内会有详细的搭建步骤 // localhost:4000 const Koa = require('koa'); const path = require('path') const static = require('koa-static') const app = new Koa(); //设置静态资源的路径 const staticPath = './static' app.use(static( path.join( __dirname,staticPath) )) console.log("服务启动在4000端口") app.listen(4000); // localhost:3000 const Koa = require('koa'); const path = require('path') const static = require('koa-static') const app = new Koa(); //设置静态资源的路径 const staticPath = './static' app.use(static( path.join( __dirname,staticPath) )) console.log("服务启动在4000端口") app.listen(4000);

HTML5 postMessage 和 onmessage API 详细应用

HTML5 postMessage 和 onmessage API 详细应用

       Web Workers

       Web Workers 简介

       至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能。它不但强化了 Web 系统或网页的表现性能,而且还增加了对本地数据库等 Web 应用功能的支持。其中,最重要的一个便是对多线程的支持。在 HTML5 中提出了工作线程(Web Workers)的概念,并且规范出 Web Workers 的三大主要特征:能够长时间运行(响应),理想的启动性能以及理想的内存消耗。Web Workers 允许开发人员编写能够长时间运行而不被用户所中断的后台程序,去执行事务或者逻辑,并同时保证页面对用户的及时响应。

       Web Workers 为 Web 前端网页上的脚本提供了一种能在后台进程中运行的方法。一旦它被创建,Web Workers 就可以通过 postMessage 向任务池发送任务请求,执行完之后再通过 postMessage 返回消息给创建者指定的事件处理程序 ( 通过 onmessage 进行捕获 )。Web Workers 进程能够在不影响用户界面的情况下处理任务,并且,它还可以使用 XMLHttpRequest 来处理 I/O,但通常,后台进程(包括 Web Workers 进程)不能对 DOM 进行操作。如果希望后台程序处理的结果能够改变 DOM,只能通过返回消息给创建者的回调函数进行处理。

       浏览器对 HTML5 支持情况可以参考网站 When can I use...

       在 Web Workers 中使用 postMessage 和 onmessage

       首先,需要在客户端页面的 JavaScript 代码中 new 一个 Worker 实例出来,参数是需要在另一个线程中运行的 JavaScript 文件名称。然后在这个实例上监听 onmessage 事件。最后另一个线程中的 JavaScript 就可以通过调用 postMessage 方法在这两个线程间传递数据了。

       清单 1. 主线程中创建 Worker 实例,并监听 onmessage 事件

Test Web worker function init(){ var worker = new Worker(''compute.js''); //event 参数中有 data 属性,就是子线程中返回的结果数据 worker.onmessage= function (event) { // 把子线程返回的结果添加到 div 上 document.getElementById("result").innerHTML += event.data+""; }; }

       在客户端的 compute.js 中,只是简单的重复多次加和操作,最后通过 postMessage 方法把结果返回给主线程,目的就是等待一段时间。而在这段时间内,主线程不应该被阻塞,用户可以通过拖拽浏览器,变大缩小浏览器窗口等操作测试这一现象。这个非阻塞主线程的结果就是 Web Workers 想达到的目的。

       清单 2. compute.js 中调用 postMessage 方法返回计算结果

 var i=0;

function timedCount(){
for(var j=0,sum=0;j for(var i=0;i sum+=i;
}
}
// 调用 postMessage 向主线程发送消息
postMessage(sum);
}

postMessage("Before computing,"+new Date());
timedCount();
postMessage("After computing,"+new Date());

HTML5 postMessage 和 onmessage API 详细应用

 1. 浏览器中运行结果

       Cross-document messaging

       Cross-document messaging 简介

       由于同源策略的限制,JavaScript 跨域的问题,一直是一个颇为棘手的问题。HTML5 提供了在网页文档之间互相接收与发送信息的功能。使用这个功能,只要获取到网页所在窗口对象的实例,不仅同源(域 + 端口号)的 Web 网页之间可以互相通信,甚至可以实现跨域通信。 要想接收从其他窗口发送来的信息,必须对窗口对象的 onmessage 事件进行监听,其它窗口可以通过 postMessage 方法来传递数据。该方法使用两个参数:第一个参数为所发送的消息文本,但也可以是任何 JavaScript 对象(通过 JSON 转换对象为文本),第二个参数为接收消息的对象窗口的 URL 地址,可以在 URL 地址字符串中使用通配符''*''指定全部地。

       在 Cross-document messaging 中使用 postMessage 和 onmessage

       为了实现不同域之间的通信,需要在操作系统的 hosts 文件添加两个域名,进行模拟。

       清单 3. hosts 文件中添加两个不同的域名

127.0.0.1 parent.com
127.0.0.1 child.com

       在父网页中通过 iframe 嵌入子页面,并在 JavaScript 代码中调用 postMessage 方法发送数据到子窗口。

       清单 4. 父页面中嵌入子页面,调用 postMessage 方法发送数据



Test Cross-domain communication using HTML5








value="Send to child.com" onclick="sendIt()" />


       在子窗口中监听 onmessage 事件,并用 JavaScript 实现显示父窗口发送过来的数据。

       清单 5. 子窗口中监听 onmessage 事件,显示父窗口发送来的数据




Web page from child.com



Web page from http://child.com:8080



HTML5 postMessage 和 onmessage API 详细应用

图 2. 父窗口嵌入子窗口

HTML5 postMessage 和 onmessage API 详细应用

图 3. 父窗口发送数据到子窗口

       WebSockets

       WebSockets 简介

       在 Web 应用中,HTTP 协议决定了客户端和服务端连接是短连接,即客户端 Request,服务端 Response,连接断开。要想实现客户端和服务端实时通信,只能通过客户端轮询来实现。服务端推送数据也并不是字面上意思上的直接推,其实还是客户端自己取。WebSockets 是 HTML5 规范新引入的功能,用于解决浏览器与后台服务器双向通讯的问题,使用 WebSockets 技术,后台可以随时向前端推送消息,以保证前后台状态统一。

       在 WebSockets 中使用 send 和 onmessage

       由于文本主要介绍 postMessage(send) 和 onmessage 客户端 API 的应用,而 WebSockets 涉及到服务器端代码的实现,所以本文将选取最简单的服务器端框架来编写服务器代码。WebSockets 服务器端有 jetty 提供的基于 Java 的实现,有 WebSocket-Node 基于 node.js 的实现,在 .Net 4.5 中也直接提供了 WebSockets 的支持。本文将使用 WebSocket-Node 提供的示例代码,稍作修改作为 WebSockets 的服务器端。关于 node.js 的介绍以及使用请参考 node.js 官方网站 node.js,关于 WebSocket-Node 的使用请参考 WebSocket-Node。

       首先,需要在客户端通过 JavaScript 代码 new 一个 WebSocket 实例出来,参数是实现 WebSocket 服务器端 URL 地址。然后在这个实例上监听 onmessage 事件接收服务器端发送过来的数据。当然,客户端也可以调用 send 方法,发送数据到服务器端。

       清单 6. 创建 WebSocket 对象,并监听 onmessage 事件


connect : function() {
var location ="ws://localhost:8000/";
// 创建 WebSockets 并传入 WebSockets server 地址
this._ws =new WebSocket(location);
this._ws.onmessage=this._onmessage;
//WebSockets 还提供了 onopen 以及 onclose 事件
this._ws.onopen =this._onopen;
this._ws.onclose =this._onclose;
}

       在 _onmessage 方法中,接收数据,并显示在页面上

       清单 7. _onmessage 方法

 _onmessage : function(event) {
//event 参数中有 data 属性,就是服务器发送过来的数据
if (event.data) {
var messageBox = document.getElementById(''messageBox'');
var spanText = document.createElement(''span'');
spanText.className =''text'';
// 把服务器发送过来的数据显示在窗口中
spanText.innerHTML = event.data;
var lineBreak = document.createElement(''br'');
messageBox.appendChild(spanText);
messageBox.appendChild(lineBreak);
messageBox.scrollTop = messageBox.scrollHeight
- messageBox.clientHeight;
}
},

       在 _onopen 方法中,调用 _send 方法发送一条消息到服务器端,告之连接已经建立。在 _onclose 方法中,把 WebSocket 的实例设置成 null,释放资源。

       清单 8. _onopen,_onclose 以及 send 方法

_onopen : function() {
server._send("Client:Open WebSockets,"+new Date());
},
//message 参数就是客户端向服务器端发送的数据
_send : function(message) {
if (this._ws)
this._ws.send(message);
},
// 此方法提供外部代码调用
send : function(text) {
if (text !=null&& text.length >0)
server._send(text);
},

_onclose : function(m) {
this._ws =null;
}

       把这些方法封装在一个 server 对象中,方便提供外部调用。用户只需要先调用 server 的 connect 方法建立连接,然后调用 send 方法发送数据。

       清单 9. 封装客户端实现

var server = {
// 对外主要提供 connect 和 send 方法
connect : function() {...},
_onopen : function() {...},
_send : function(message) {...},
send : function(text) {...},
_onmessage : function(event) {...},
_onclose : function(m) {...}
};

       在服务器端,通过 JavaScript 语言简单修改 WebSocket-Node 中提供的 echo-server.js 示例即可。这里只展示关键代码部分,其它代码请参见 WebSocket-Node 示例。

       清单 10. WebSockets 服务器端简单实现

// 监听客户端的连接请求
wsServer.on(''connect'', function(connection) {
function sendCallback(err) {
if (err) console.error("send() error: " + err);
}
// 监听客户端发送数据的请求
connection.on(''message'', function(message) {
if (message.type === ''utf8'') {// 区别客户端发过来的数据是文本还是二进制类型
connection.sendUTF(
"Server:Get message:
"+message.utf8Data, sendCallback
);
}
else if (message.type === ''binary'') {
connection.sendBytes(message.binaryData, sendCallback);
}
});
connection.on(''close'', function(reasonCode, description) {
});
});

HTML5 postMessage 和 onmessage API 详细应用

图 4. 点击 Connect 按钮

HTML5 postMessage 和 onmessage API 详细应用

图 5. 输入内容,单击 Send Message 按钮

       Server-Sent Events

       Server-Sent Events 简介

       HTML5 Server-Sent 事件模型允许您从服务器 push 实时数据到浏览器。本文我们将介绍利用 Eventsource 对象处理与页面间的接收和发送数据。在客户端,我们使用 HTML5+JavaScript,服务端使用 Java。在现存的 Ajax 模式中,web 页面会持续不断地请求服务器传输新数据,由客户端负责请求数据。而在服务端发送模式下,无需在客户端代码中执行连续的数据请求,而是由服务端 push 推送更新。一旦您在页面中初始化了 Server-Sent 事件,服务端脚本将持续地发送更新。客户端 JavaScript 代码一旦接收到更新就将新的数据写入页面中展示出来。

       在 Server-Sent Events 中使用 onmessage

       Server-Sent Events 和 WebSockets 有相同之处,WebSockets 实现了服务器端以及客户端的双向通信功能,而 Server-Sent Events 则仅是指服务器端到客户端的单向通信,而且 Server-Sent Events 同样需要服务器端的实现,本文将使用基于 Java 的 Servlet 技术实现服务器端。关于服务器端向客户端写数据的格式,可以参考 W3C 关于 Server-Sent Events 的规范文档 Server-Sent Events。由于是服务器端到客户端的单向通信,所以在 Server-Sent Events 中没有 postMessage 方法。
首先,在客户端通过 JavaScript 代码 new 一个 EventSource 实例出来,参数是实现 EventSource 服务器端 URL 地址。然后在这个实例上监听 onmessage 事件接收服务器端发送过来的数据。

       清单 11. 创建 EventSource 对象,并监听 onmessage 事件
if (!!window.EventSource) {
// 创建 EventSource 实例,传入 server 地址
var source = new EventSource(''/TestHTML5/ServerSentEvent'');
} else {
console.log("Your browser doesn''t support server-sent event");
}
// 监听 message 事件,等待接收服务器端发送过来的数据
source.addEventListener(''message'', function(event) {
//event 参数中有 data 属性,就是服务器发送过来的数据
console.log(event.data);
}, false);

//EventSource 还提供了 onopen 以及 onerror 事件
source.addEventListener(''open'', function(event) {
}, false);

source.addEventListener(''error'', function(event) {
if (event.readyState == EventSource.CLOSED) {
}
}, false);

       服务器端,在 Java 语言实现的 Servlet doGet 方法中使用 response 对象向客户端写数据

       清单 12. 服务器端简单实现

// 这里必须设置 Content-Type 为 text/event-stream
response.setHeader("Content-Type", "text/event-stream");
response.setHeader("Cache-Control", "no-cache");
response.setCharacterEncoding ("UTF-8");

String id = new Date().toString();
response.getWriter().println("id:"+id);
// 向客户端写两行数据
response.getWriter().println("data:server-sent event is working.");
response.getWriter().println("data:test server-sent event multi-line data");
response.getWriter().println();
response.getWriter().flush();

HTML5 postMessage 和 onmessage API 详细应用

图 6. Server-Sent Events 运行结果

       结束语

       本文详细介绍了 postMessage(send)和 onmessage API 在客户端的应用情况,可以看到在不同的场景中这两个方法的应用模式都是类似的。postMessage 的作用就是传递数据,而 onmessage 的作用就是接收数据。掌握此组 API 对以后开发 HTML 5 应用程序将会有所帮助。本文 Web Workers,Cross-document messaging,WebSockets 的代码在 Firefox 14 下通过测试,Server-Sent Events 的代码在 Chrome 16 下通过测试。

HTML5 postMessage 消息传输与 POST 跨域通信

HTML5 postMessage 消息传输与 POST 跨域通信


HTML5 的 postMessage 方法可实现不同窗体间互相通信。

postMessage 支持实现跨文档消息传输(Cross Document Messaging),并且可跨域传输信息。Internet Explorer 8,Firefox 3,Opera 9,Chrome 3和 Safari 4 以上版本浏览器都已支持 postMessage。

1. postMessage 功能简介

postMessage 主要包含两个 API:

1).消息监听:onmessage
2).消息发送:postMessage

使用步骤也很简单:

1.1.监听发送过来的消息

1 window.addEventListener('message',onMessage, false);
2  
3 var onMessage = function(){
4     console.log(e,e.data);
5     if(e.origin !="http://lzw.me"){
6         return ;
7 }
8     // 消息处理...
9 }

注意:

e.data 即接收到的信息。
由于该监听可接收任意发送过来的消息,故一般应对 e.origin 来源进行检测,如果不是预设的消息来源,应予以拒绝处理。

1.2.向其他窗体发送消息

首先获取要传送消息的窗体对象(如iframe),然后向该对象发送信息

iframeWin = document.getElementsByTagName('iframe')[0].contentwindow;
iframeWin.postMessage('Hello World!'rush plain"https://www.jb51.cc/tag/ott/" target="_blank">ottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; font-family:Consolas, "*");

HTML5 postMessage 跨域交换数据

HTML5 postMessage 跨域交换数据

        今天我们来学习一下HTML5的api,利用postMessage来跨域交换数据。和前面一些方式交换数据方式不同的是,利用postMessage不能和服务端交换数据只能在两个窗口(iframe)之间交换数据,废话不多说,我们直接进入实战。

实战postMessage

  • overview

  上文中说,postMessage是用于两个窗口(iframe)之间交换数据的,如果我们同时打开着百度和谷歌两个页面,是不是说这两者之间就可以通信了?No,no,no,事实并非如此,就算百度和谷歌俩页面有通信的意愿也不行。两个窗口能通信的前提是,一个窗口以iframe的形式存在于另一个窗口,或者一个窗口是从另一个窗口通过window.open()或者超链接的形式打开的(同样可以用window.opener获取源窗口);换句话说,你要交换数据,必须能获取目标窗口(target window)的引用,不然两个窗口之间毫无联系,想通信也无能为力。

  既然是H5家族的,我们也得观望下它被广大浏览器的接受程度,可以看到接受程度还是相当高的:

  而postMessage的使用方式也相当简单:

otherWindow.postMessage(message, targetOrigin, [transfer]);

  otherWindow是对接收方窗口的引用,一般可以是以下几种方式:

window.frames[0].postMessagedocument.getElementsByTagName(''iframe'')[0].contentWindow
window.opener.postMessage
event.source.postMessage
window.open 返回的引用
...

  而message顾名思义就是发送的数据内容,支持字符串、数字、json等几乎所有形式的数据

  targetOrigin是接收方的URI(协议+主机+端口),也可以是url形式,但之后的内容(形如xx.html)会自动忽略;用通配符*可以指定所有域,但是切记不要用(for security)。

  transfer可省略,没看懂是啥意思...以后有需要的时候再研究

  而接受方窗口一般监听message事件,详见下面的例子。

  • window <-> iframe

  假设index页面有个iframe(不同源),我们要给iframe发送数据,而iframe得到数据后也发送数据给top window,表示“我"得到数据了。直接看源码(思考如何发送and如何接收):

<!-- http://localhost:81/fish/index.html --><script type="text/javascript">  // 页面加载完后才能获取dom节点(iframe)
  window.onload = function(){    // 向目标源发送数据
    document.getElementsByTagName(''iframe'')[0].contentWindow.postMessage({"age":10}, ''http://localhost:8080'');
  };  // 监听有没有数据发送过来
  window.addEventListener(''message'', function(e) {
      console.log(e);
  });</script>
<iframe src="http://localhost:8080/index.html"></iframe>

 

 

<!-- http://localhost:8080/index.html --><script type="text/javascript">  // 监听有没有数据发送过来
  window.addEventListener(''message'', function(e){      // 判断数据发送方是否是可靠的地址
      if(e.origin !== ''http://localhost:81'')        return;    // 打印数据格式    console.log(e);    // 回发数据
    e.source.postMessage(''hello world'', e.origin);
  }, false);</script>

  我们截图看看打印的东西究竟长什么样(index页面传给iframe的数据):

  红框标出的是三个最重要的属性,data顾名思义就是传输的数据了;origin就是发送消息窗口的源(URI 协议+主机+端口);而source就能引用发送消息的窗口对象(可以用它来引用发送窗口进行消息回传)。

   在消息接收端监听可以监听message事件(代码如上),当然如果要兼容坑爹的ie肯定要用attachEvent。这里不推荐使用window.onmessage,兼容性不大好(比如不能兼容低版本ff)。

  • window <-> window

  说完了跟同一页面中的iframe的数据交换,再来说说两个窗口之间的数据交换。我们知道用window.open()可以打开一个新的窗口,而如果两个窗口同源,则两个窗口的通信将会非常简单,我们可以通过window.opener.functionName在新窗口中调用原来窗口的方法(和变量)。但是如果两个窗口不同源,这样的操作将会变得很艰难,幸运的是H5给我们提供了postMessage,使得window.opener.postMessage()不会报错!demo很简单:

<!-- http://localhost:81/fish/index.html --><script type="text/javascript">  // 打开一个新的窗口
  var popup = window.open(''http://localhost:8080/index.html'');  /// When the popup has fully loaded, if not blocked by a popup blocker:
  setTimeout(function() {      // 当前窗口向目标源传数据
    popup.postMessage({"age":10}, ''http://localhost:8080'');
  }, 1000);</script>

 

 

<!-- http://localhost:8080/index.html --><script type="text/javascript"> 
  // 设置监听,如果有数据传过来,则打印
  window.addEventListener(''message'', function(e) {
    console.log(e);    // console.log(e.source === window.opener);  // true  });</script>

  这里要设置一个定时器的原因是向目标窗口发送数据必须等目标窗口完全加载完,也就是说要在目标窗口中先设置好“监听器”,发送窗口发的数据才能被监听到,所以给了个定时器delay,而因为加载时间的不确定所以定时器的delay值也不能确定;另外一个可行的办法是当目标页面加载完后,发个消息个源页面(postMessage),而源页面收到消息,再用postMessage发送消息给目标页面。

安全顾虑

  提到跨域交换数据,条件反射都会问一句,安全吗?对于postMessage,肯定是安全的。

  postMessage采用的是“双向安全机制”。发送方发送数据的时候,会确认接受方的源(所以最好不要用*),而接受方监听到message事件后,也可以用event.origin判断是否来自于正确可靠的发送方。


HTML5 postMessage 跨域跨窗口传递消息

HTML5 postMessage 跨域跨窗口传递消息

父页面代码:

<!DOCTYPE html>
<htmlhead>
    title>选择位置demo</>

    Meta charset="utf-8" />
    http-equiv="X-UA-Compatible" content="IE=edge"name="viewport"="width=device-width,initial-scale=1"script type="text/javascript" src="dist/jquery-1.7.1.js"></script="libs/layer/layer.js"bodyiframe id="ifr"="http://10.100.10.167:8061" style="width: 1200px; height: 800px;"iframe="text/javascript">
        $("#ifr).load(function () {
            var data = {
                method: selectLocation,url: window.location.href,lng: 113.1323.01
            };

            //给地图页面发消息
            window.ifr.contentwindow.postMessage(JSON.stringify(data),ifr.src);
        });

        监听消息
        window.addEventListener(message (e) {
             d  eval((" + e.data + ));

            if (d.method == selectLocationComplateCallback) {
                layer.alert(d.lng.toFixed(7)  d.lat.toFixed(),{ title: 信息 });
            }
        });
    >
View Code

子页面JS代码:

//监听父页面发来的消息
window.addEventListener("message",function (e) {
    var d = eval("(" + e.data + ")");

    if (d.method == "selectLocation") {
        if (d.lat && d.lng) drawUtil.setSelectedLocation(d.lng,d.lat); 设置已选择的位置坐标

        selectLocation();

        选择位置完成回调
        selectLocationComplateCallback =  (lat,lng) {
            var data = {
                method: "selectLocationComplateCallback"View Code

 

总结

以上是小编为你收集整理的HTML5 postMessage 跨域跨窗口传递消息全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

原文地址:https://www.cnblogs.com/s0611163

今天的关于html5 postMessage前端跨域并前端监听的方法示例前端post解决跨域的方法的分享已经结束,谢谢您的关注,如果想了解更多关于HTML5 postMessage 和 onmessage API 详细应用、HTML5 postMessage 消息传输与 POST 跨域通信、HTML5 postMessage 跨域交换数据、HTML5 postMessage 跨域跨窗口传递消息的相关知识,请在本站进行查询。

本文标签: