【红宝书笔记】跨域访问资源和web通信

来源:互联网 发布:英文版遗传算法 编辑:程序博客网 时间:2024/06/10 02:05

ajax可以实现异步和同步,但是无法跨域访问资源。

主要的跨域访问有CORS,jsonp,comet,websocket等。

先说说什么是跨域:对于资源的访问,只要是来自不同协议(http,https..)或者不同域名(www.xx.com,www.yy.com,或者是域名对应的ip地址,或者是网站的子域)或者不同的端口号都是跨域访问。

处于安全因素的考虑,跨域一半都是不被允许的。因为如果有人可以随意访问你服务器上的资源,那么。。。0 0。。。。

1.CORS(cross-origin resource sharing)

主要实现的方法是在请求的头部加上Origin,包含请求页面的源信息(域名,协议,端口)。然后服务器根据这个信息判断是否要进行相应,如果要的话,就在response的头部加上Access-Control-Allow-Origin:请求页面的源信息。如果不加,或者不匹配,浏览器就驳回这个请求。注意这时请求和相应都是不包含cookie信息的。

2.JSONP,图片Ping

据说在CORS出现之前,常用JSONP和Ping进行跨域的资源访问,两者的访问原理都相同,使用页面中可以进行跨域访问资源的标签进行资源的获取。

JSONP:

由于<script>标签是可以跨域加载资源的,所以在该标签的src上加上访问的内容和回调函数,当请求的信息加载到页面之后,就可以通过本地的callback函数对数据进行处理了。(当把多个js文件加载到一个页面下的时候,这些js就是共享的了,互相可以访问)。

<span style="font-size:18px;color:#333333;">function a(){console.log("1111");}</span>
a是callback函数,想要在请求结束之后调用callback函数,服务器要在返回的数据中添加a函数调用的文本。

在页面中添加请求:

<span style="font-size:18px;color:#333333;"><script type="text/javascript" src="http://localhost:3000/jsonp?callback=a"></script></span>

如下是用express搭建的服务器:

<span style="font-size:18px;color:#333333;">router.get('/jsonp',function(req, res, next) {  // console.log(req);  var ques = req.query;  res.send("console.log('GET啦');"+ques.callback+"();");});</span>
表示在接受到这么一个路径下的访问的时候,返回send中的信息(这些文本都是js代码)

于是在加载成功之后看控制台:


表示成功运行了script标签返回的js代码

优点:可以访问返回的信息

缺点:不够安全,不好确定请求是否成功,只能用get方法.

虽然H5中增加了onerror方法,但是貌似支持还不是很好。。

Ping:

和jsonp的原理一样,图像可以跨域加载,所以可以这样:

<span style="font-size:18px;color:#333333;">var img = new Image();img.onload = function(){    console.log("finished");};img.src="http://xx.com:8080/test?name=query"</span>

在指定了img的src之后,就对相应的地址发送了包含name的一个请求。

缺点:不能访问服务器返回的信息。。,只能用get方法

2.5 document.domain, window.name

这个主要是不同iframe之间的通信。比如说两个frame之间是不同域的,但是主域相同,就可以通过修改document.domain来进行域名的提升(只能设置成自身或者更高一级的父域)。这样就可以进行同源访问了。

window.name是这个窗口中所有历史页面都可以访问的属性,并且每个页面对于这个属性都有读写权,可以通过把数据放在window.name来进行交互。

3.comet

以上还是跨域资源方面的请求,从comet开始应该算是web间的通信了吧。comet是服务器向页面推送数数据的技术

comet主要通过长轮询和http流实现通信。

3.1长轮询

短轮训是每请求一个资源,就发送一次http的请求。而长轮询是客户端向服务器发起请求后,服务器就挂起了这个请求,不回应客户端,这样这个http的请求就一直开启,直到服务器发现有消息需要推送了,就拿着消息响应客户端,然后客户端收到消息之后马上再发送新的一个http请求,以此来保持联系。

3.2http流

http流在整个页面的生命周期中只有一次http请求,服务器周期性地像客户端推送消息,并且不关闭连接。而客户端可以通过XHR的readyState来获取消息。因为对于readyState,0表示没有初始化,1表示建立连接,但没发送,2表示已发送,正在处理,3表示正在处理,4表示响应完成。

所以监听readyState,当它为3的时候,就通过游标来获得新得到的数据:

<span style="font-size:18px;color:#333333;">var xhr = new XMLHttpRequest(),receive = 0; //游标xhr.open("get",url,true);xhr.onreadystatechange = function(){var ret;if(xhr.readystate == 3){ret = xhr.responseText.substring(receive);receive +=ret.length;callback(ret);}else if(xhr.readystate == 4){Finished();}xhr.send(null);return xhr;}</span>
3.3 SSE

Server-Sent Events,是支持comet的api。

通过:

<span style="font-size:18px;color:#333333;">var source = new EventSource(url); //url需要和页面同源的</span>
开启连接,sse支持长轮询和http流,在连接断开的时候回自动再连接。如果不想再连接了,可以通过source.close()关闭连接。

source有三个事件,open,message,error分别在建立连接,从服务器接受新事件,出错的时候触发。

4.websocket

听说有通过websocket制定的分屏应用,感觉好有趣=w=,希望什么时候能试试

websocket协议是在http的基础上定制的协议,虽然有http的头部,但是之后貌似和http就没有关系了。未加密的协议是ws://,加密的协议是wss://

websocket比较方便,但是对于服务器的要求高,因为服务器需要支持websocket。

它没有同源策略的限制,是否通信只取决于服务器。有三个事件:open,error,close。由于不支持dom2级事件,所以要用dom0级来绑定事件。



0 0