呵呵呵呵,,,,最近好烦躁!
在项目开发中大多数都会用到ajax来实现动态数据获取,但是ajax受同源策略的影响无法跨域,于是就出现了各种跨域手段和技术,jsonp、cors、iframe等。jsonp之前有篇文章已经介绍过了,这里主要介绍一下cors。
cors(跨域资源共享)是W3C的一个工作草案,定义了在必须访问跨域资源的时候,浏览器和服务器应该如何沟通。CORS背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或者响应式应该成功或者失败。
在服务器端如果认为这个请求(非同域)可以接受,就会在响应头部中发回Access-Control-Allow-Origin和源信息(如果是公共资源,可以发回'*'),例如:
Access-Control-Allow-Origin:114.215.80.72:80
如果没有这个响应头部或者响应头部源信息不匹配,浏览器就会驳回请求,正常情况下,浏览器会处理请求,但是有一点要注意:请求和响应中不包含cookie信息。
接下来说一下实现方法,基本上前端js谈到实现无外乎两种问题,IE和其他,cros也一样,不过有一点的是cors在IE的兼容性是IE8+,移动端除了opera mini其他都兼容,所以说在移动端的支持还是很好的。
IE对CORS的实现
微软在IE8中引入的XDR(XDomainRequest)类型,这个类型和XHR类似,但能实现安全可靠的跨域通信。
XDR对象的使用方法与XHR对象非常类似,也是创建一个XDomainRequest对象的实例,然后调用open方法,再调用send方法,但是与XHR的open方法不同的是XDR的open方法只接受两个参数:请求类型和url。所以说XDR的请求都是异步的,不能用来创建同步,请求返回之后虎触发load事件,响应的数据也会保存到responseText中 ,为了捕获错误可以使用onerror方法,虽然其只能捕获错误本身,不能捕获到其他任意信息。
代码实现:
var xdr = new XDomainRequest(); xdr.onload = function(){ alert(xdr.responseText) }; xdr.onerror = function(){ alert('error') }; xdr.open('get','114.215.80.72:80'); xdr.send(null);
其他浏览器对CORS的实现
其他浏览器都是通过XMLHttpRequest对象实现对CORS的原声支持,与IE不同的是跨域XHR对象可以访问status和statusText属性,而且还支持同步请求。跨域XHR对象也有以下限制,但是为了安全这些限制是必须的:
1、不能使用serRequestHeader()设置自定义头部
2、不能发送和接收cookie
3、调用gerAllResponseHeaders()方法总会返回空字符串
代码实现:
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState==4&&(xhr.status==(200|304|202))){ alert(xhr.responseText); } } xhr.open('get','http://www.manster.me:80',true); xhr.send(null);
跨浏览器兼容方案
即使浏览器对CORS的支持程度并不都一样,但是所有浏览器都支持简单的请求,因此很有必要实现一个跨浏览器的方案。检测XHR是否支持CORS的最简单的方案就是检查是否存在withCreDentials属性。在结合检测XDomainRequest对象是否存在,就可以兼顾所有浏览器了。
兼容代码:
// 高级浏览器 // 获取跨域资源共享的对象 var getCORS = function () { if (window.XDomainRequest) { return new XDomainRequest(); } if (window.XMLHttpRequest) { var xhr = new XMLHttpRequest(); if (xhr.withCredentials !== void 0) { return xhr; } throw new Error('不支持cors'); } throw new Error('不支持cors'); }; var cors = getCORS(); cors.open('post', 'http://www.manster.me:80', true); // onload执行的时机与xhr.readyState为4的时候相同 cors.onload = function () { if (cors.status === 200) { console.log(cors.responseText); } };
无论是XDmainRequest对象还是XMLHttpRequest对象都共同支持的属性和方法有:
- abort() :用于停止正在进行得到请求;
- onerror:用于替代onreadystatechange检测错误
- onload:用于替代onreadystatechange检测成功
- responseText:用于取得响应内容
- send():用于发送请求。
以上的成员都包含在createCORSRequest()函数返回的对象中,在所有的浏览器中都能正常使用。
文章评论