javascript 跨域方法总结

来源:互联网 发布:小提琴 曲 知乎 编辑:程序博客网 时间:2024/05/18 01:30

  通过XHR实现Ajax通信的一个主要限制,来源于同源策略。默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。这种安全策略可以预防某些恶意行为。但是,实现合理的跨域请求对开发某些浏览器应用程序也至关重要。

 一、CORS (Cross-Orign Resource Sharing) 跨源资源共享

CORS是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
(1)非IE浏览器

FireFox 3.5+ 、Safari 4+、Chrome、iOS版Safari和Android平台中的Webkit都通过XMLHttpRequest对象实现了对CORS 的原生支持。在尝试打开不同来源的资源时,无需额外的编写代码就可以实现触发这个行为。要请求位于另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL即可,同时还要在服务器端设置Access-Control-Allow-Origin;

 当你使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。



  前端:
  var xhr=new XMLHttpRequest();  xhr.onreadystatechange=function(){     if(xhr.readState==4){      if((xhr.status>=200&&xhr.status<300)||xhr.status==304){                    console.log(xhr.responseText) ;        }else{            console.log("Failed!");        }         }  } xhr.open("get","http://www.somewhere.com/page/",true); xhr.send(null);


后台:

header("Access-Control-Allow-Origin: *");  或者header("Access-Control-Allow-Origin:http://www.somewhere.com ");

与IE的XDR对象不同,跨域的XHR对象可以访问status和statusText属性,而且支持同步请求。

跨域的XHR对象也有一些限制,为了安全这些限制是必要的,以下就是这些限制:

 1)不能使用setRequestHeader()设置自定义头部。
 2)不能发送和接收cookie
 3)调用getAllResponseHeaders()方法总会返回空字符串


(2)IE浏览器


微软在IE8中,引入了XDR(XDomainRequest)类型。这个对象与XHR类似,但能实现安全可靠的跨域通信。XDR与XHR有一些不同之处。

  1.cookie不会随请求发送,也不会随响应返回。
  2.只能设置请求头部信息中的Content-Type字段。
  3.不能访问响应头部信息
  4.只支持GET和POST请求

例:

var xdr=new XDomainRequest();xdr.onload=function(){  alert(xdr.responseText);}xdr.onerror=function(){alert("Error");}xdr.open("get","http://www.somewhere.com/page/");xdr.send(null);


XDR对象的open方法只接受两个参数:请求的类型和URL。
所有XDR请求都是异步的,不能创建同步请求。

在接收到响应后,你只能访问响应的原始文本;没有办法确定响应的状态代码。而且只要响应有效就会触发load事件,如果失败(包括响应中缺少Access-Control-Allow-Origin头部)就会触发error事件。

 二、图像Ping

 动态创建图像经常用于图像Ping。图像Ping是与服务器进行简单、单向的跨域通信的一种方式。请求的数据时通过查询字符串的形式发送的,而响应可以是任意的内容。通过图像Ping,浏览器得不到任何具体的数据,但通过监听load和error事件,它知道响应是什么时候接收到的。
  
  var img=new Image();    img.load=function(){       alert("ok");   }  img.onerror=function(){  alert("Failed");}img.src="http://www.somewhere.com/example.gif";



图像Ping技术最常用于跟踪用户点击页面或动态广告曝光次数。图像Ping技术的两个缺点: 1,只能发送GET请求 ,二,无法访问服务器的响应文本。

三、JSONP

JSONP 是JSON with padding的简写,是应用JSON的一种新方法,在后来的web应用中非常流行。

JSONP由两部分构成:回调函数和数据。回调函数是当响应到来 时应该在页面中调用的函数。回调函数一般在请求中指定的。而数据就是传入回调函数中的JSON数据。例如:

http://somewhere.com/?callback=handlerResponse
前端代码:

function handleResponse(data){ alert(data);}  var script=document.createElement("script");script.src="http://somewhere.com/?code=CA1929&callback=handlerResponse";document.body.insertBefore(script,document.body.firstChild);





后台要动态生成js文件。

(详见:http://blog.csdn.net/vuturn/article/details/44887623)

缺点:
1.安全性问题
2.要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定

四、Comet

comet是一种更高级的AJAX技术(也有人称为是服务器推送)。Ajax是页面向服务器发送请求,而Comet是服务器向页面推送数据的技术。Comet能够让数据近乎实时的被推送到页面上。

有两种方式可以实现Comet:长轮询和流。长轮询是传统短轮询的一个翻版,短轮询即浏览器定时向服务器发送请求,看有没有数据更新。长轮询把短轮询颠倒了一下。页面发送请求到服务器,然后服务器一直保持连接打开,直到有数据可 发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页面打开期间一直持续不断。

无论长轮询还是短轮询,浏览器都要在接收数据之前,先发起对服务器的连接。两者最大的区别在于服务器如何发送数据。短轮询是立即发送数据,无论数据是否有效,而长轮询是等待发送响应。轮询的优势是所有的浏览器都支持,因为使用XHR对象和setTimeout()就能实现。


第二种流行的Comet实现方式是HTTP流。流不同于上述两种轮询,因为它在整个生命周期内只有一个HTTP连接。具体来说,就是浏览器向服务器发送一个请求,而服务器发送一个请求,而服务器保持连接打开,然后周期性的发送请求。

五.Web Sockets

Web Sockets 的目标是实现在一个单独的持久连接上提供全双工、双向通信。在Javascript中创建了Web Socket之后,会有一个HTTP请求发送到浏览器以发起连接。在取得服务器的响应之后,建立的连接会使用HTTP升级从HTTP协议交换为Web Socket协议。使用标准的HTTP服务器无法实现Web Sockets ,只要支持这种协议的服务器才能正常工作。Web Sockets非常适合移动应用。

要创建Web Socket,先实例一个WebSocket对象并传入要连接的URL。

var socket=new  WebSocket("ws://www.example.com/index.php");

必须要给WebSocket传入绝对URL。同源策略对Web Sockets不适用,因此可以通过它打开任意站点的连接。



 








  
  

0 0
原创粉丝点击