愚墨的博客
  • 首页
  • 前端技术
  • 面试
只争朝夕不负韶华
  1. 首页
  2. 前端技术
  3. 正文

CORS

2016年07月30日 2664点热度 0人点赞 0条评论

呵呵呵呵,,,,最近好烦躁!

在项目开发中大多数都会用到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对象都共同支持的属性和方法有:

  1. abort() :用于停止正在进行得到请求;
  2. onerror:用于替代onreadystatechange检测错误
  3. onload:用于替代onreadystatechange检测成功
  4. responseText:用于取得响应内容
  5. send():用于发送请求。

7b73BfGE4B

以上的成员都包含在createCORSRequest()函数返回的对象中,在所有的浏览器中都能正常使用。


 

标签: 暂无
最后更新:2016年08月02日

愚墨

保持饥渴的专注,追求最佳的品质

点赞
< 上一篇
下一篇 >

文章评论

取消回复

搜搜看看
历史遗迹
  • 2023年5月
  • 2022年9月
  • 2022年3月
  • 2022年2月
  • 2021年12月
  • 2021年8月
  • 2021年7月
  • 2021年5月
  • 2021年4月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年9月
  • 2020年7月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年1月
  • 2019年5月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年9月
  • 2018年3月
  • 2018年2月
  • 2018年1月
  • 2017年11月
  • 2017年7月
  • 2017年6月
  • 2017年3月
  • 2017年2月
  • 2017年1月
  • 2016年12月
  • 2016年11月
  • 2016年9月
  • 2016年8月
  • 2016年7月
  • 2016年6月
  • 2016年5月
  • 2016年4月
  • 2016年3月
  • 2016年2月
  • 2016年1月
  • 2015年12月
  • 2015年10月
  • 2015年9月
  • 2015年7月
  • 2015年6月
  • 2015年4月

COPYRIGHT © 2020 愚墨的博客. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS