WebSocket

背景

经常见到,但一直没在工作中用到过。一次讨论中,大概了解了一些,就是那个神奇的postMessage方法

websocket场景:

允许服务端主动向客户端推送数据。

具体问题:

问题1:
一个页面A(系统A),内嵌平台的系统B。希望能在A中感知到B的任务创建动作,有什么办法呢?A如何监听到B发出的网络请求,或者监听B某一个控件的click事件。
限制:不能改平台B系统的代码。页面A要独立完成这个功能。实在不行,再让系统B做小小的改动,支持下页面A。系统A和系统B的域名不同,非同源
问题2:
A内嵌B除了iframe嵌入,还有别的什么方法呢?

业务使用场景:

主系统A上要通过组件的方式加载一个小系统B。
点击系统A上的按钮,就可以打开系统B的窗口式界面。用户在B中填写完信息,并提交。数据就进入系统A了。但是如何让系统A知道你填完信息了呢?
这就需要系统B给系统A通信。
postMessage方法就派上用场了。系统B上的保存按钮,调到了系统A上的接口,系统A后台处理完数据,服务端就要给客户端发送请求了。
大概是这么个场景,就是不知道最后的解决方法是什么?容后再记!

假如用postmessage实现:(待完善,不一定正确)
系统B创建完任务后,主动推送消息给系统A页面
系统B的任务创建功能中要加如下代码:

worker = new Worker( url )  // url是系统A的url吧
worker.postMessage( data) 

系统A页面要加如下代码:

worker.onmessage

WebSocket是一种在单个TCP连接上进行全双工通信的协议。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

worker主线程:
1)通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。
2)通过worker.postMessage( data) 方法来向worker发送数据。
3)绑定worker.onmessage方法来接收worker发送过来的数据。
4)可以使用 worker.terminate() 来终止一个worker的执行。
WebSocket是Web应用程序的传输协议,它提供了双向的,按序到达的数据流。他是一个Html5协议,
WebSocket的连接是持久的,他通过在客户端和服务器之间保持双工连接,服务器的更新可以被及时推送给客户端,而不需要客户端以一定时间间隔去轮询。

跨域

浏览器的同源策略
同源是指相同的域名、协议和端口,只要其中一项不同就为跨域。

  • JSONP因为仅支持get请求,淘汰无人问津是迟早的事情
  • CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案,但是我们上一篇也提了,还是有IE兼容问题
  • postMessage方法允许来自不同源的脚本进行有限的通信,只要能获取到源和窗口对象就可以实现跨域消息传递
  • websocket本身不受同源策略的限制,可以在不同源间进行通信

iframe的postMessage方法

iframe页面并不能直接操作父窗口的元素。可以使用html5的postMessage()解决。
一个窗口可以获得对另一个窗口的引用,然后在窗口上调

window.postMessage()
targetWindow.postMessage()
targetWindow.postMessage(message, targetOrigin, [transfer]);
  • targetWindow: 其他窗口的一个引用。例如:window.parent父窗口
  • message: 将要发送到其他 window 的数据。
  • targetOrigin: 通过窗口的 origin 属性来指定哪些窗口能接收到消息事件。*或者url
  • transfer 可选: 是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

举例:
只有父窗口是http://a.123.com:8080时才会接受到传递的消息。

window.parent.postMessage('hello world','http://a.123.com:8080/index.html')

ifame父子窗口通信(子通信父)

子对父说,关闭iframe targetWindow.postMessage(data, '*')
父监听到子发的消息,然后做了相应的处理

window.addEventListener('message', function(e) {
var e = e || window.event;
switch (e.data.command) {
case 'close': document.getElementByTagName('body')[0].removeChild(document.getElementByTagName('ifram')[0]);
}
})

在这里插入图片描述
a.html窗口对window.open新打开的b.html窗口进行通信
在这里插入图片描述
在这里插入图片描述

跨域会引起的安全问题

安全问题
1、如果你不希望从其他网站接收message,请不要为message事件添加任何事件监听。
2、如果你确实希望从其他网站接收message,请始终使用origin和source属性验证发件人的身份。任何窗口都可以向任何其他窗口发送消息,并且你不能保证未知发件人不会发送恶意消息。而且在验证身份后,你仍然应该验证接收到的消息的语法,防止非法攻击(例如SQL注入)。
3、使用postMessage将数据发送到其他窗口时,应该指定精确的目标origin,而不是*。恶意网站可以在你不知情的情况下更改窗口的位置,因此它可以拦截使用postMessage发送的数据。

如何解决跨域问题

JSONP:
原理是:动态插入script标签,通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url
参数中指定的函数,并且会把我们需要的json数据作为参数传入。
由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域
请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨
域的数据请求。
优点是兼容性好,简单易用,支持浏览器与服务器双向通信。缺点是只支持GET请求。
JSONP:json+padding(内填充),顾名思义,就是把JSON填充到一个盒子里

代码
functioncreateJs(sUrl){
var oScript =document.createElement(‘script’);
oScript.type = ‘text/javascript’;
oScript.src= sUrl;
document.getElementsByTagName(‘head’)[0].appendChild(oScript);
} c
reateJs(‘jsonp.js’);
box({
‘name’: ‘test’
});
functionbox(json){
alert(json.name);
}

CORS:
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测
到相应的设置,就可以允许Ajax进行跨域的访问。
通过修改document.domain来跨子域
将子域和主域的document.domain设为同一个主域.前提条件:这两个域名必须属于同一个基础域名!而
且所用的协议,端口都要一致,否则无法利用document.domain进行跨域
主域相同的使用document.domain
使用window.name来进行跨域
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有
的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是
持久存在一个窗口载入过的所有页面中的
使用HTML5中新引进的window.postMessage方法来跨域传送数据
还有flash、在服务器上设置代理页面等跨域方式。个人认为window.name的方法既不复杂,也能兼容
到几乎所有浏览器,这真是极好的一种跨域方法。

参考:
《postMessage和webSocket》http://www.bijilu.com/1553.html
《在IFrame中使用postMessage跨域》https://www.jianshu.com/p/9e98b4e6ca0e

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值