跨域资源共享(1)

跨域资源共享

CORS(Cross-Origin Resource Sharing, 跨域资源共享)是W3C的一个草案,定义了在必须跨域访问资源时,浏览器与服务器如何沟通。其基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求是失败还是成功。
发送POST或GET请求时,没有自定义头部信息,主题内容为text/plain,需要添加一个额外的Origin头部,其中包含请求页面的源信息(协议、域名和端口)。
Origin : http://www.nczonline.net
如果服务器可以接受这个请求,就在Access-Control-Allow-Origin头部中回发相同的源信息,公共资源可以发回*
Access-Control-Allow-Origin : http://www.nczonline.net
请求和响应都不包含cookie信息

IE对CORS的实现

XDR类型:XDomainRequest
XDR与XHR的区别

  • cookie不会随请求发送,也不会随响应返回
  • 只能设置请求头部信息中的Context-Type字段
  • 不能访问响应头部信息
  • 只支持GET和POST请求
//GET请求
var xdr = new XDomainRequest();
xdr.onload = function() {
    alert(xdr.responseText);
}
xdr.onerror = function() {
    alert("An error occured");
}
xdr.timeout = 1000;
xdr.ontimeout = function() {
    alert("Request took too long");
}
xdr.open("get","http://example.com/page/");
//xdr.open("post","http://example.com/page/");
//xdr.contentType = "application/x-www-form-urlencoded";
xdr.send(null);
  • XDR使用方法和XHR类似,先创建一个XDomianRequest对象,调用open方法,再调用send方法
  • XDR的open方法只支持两个参数,请求方式和URL
  • XDR请求都是异步的,不能创建同步请求
  • 请求返回后,触发onload事件,响应的事件也会保存在responseText属性中
  • 响应如果失败,就会触发error事件,但是除了错误本身外,没有任何其他信息
  • 在请求返回前可以使用abort()方法终止请求
  • 与XHR一样,XDR也支持timeout属性以及ontimeout事件处理程序
  • 对于POST请求,提供了contentType属性,用来表示发送数据的格式

其他浏览器对CORS的支持

FireFox 3.5+、Safari 4+、Chrome、iOS版Safari和Andriod平台中的Webkit都通过XHR对象实现了对CORS的原生支持,使用标准XHR对象并在open方法中传入绝对URL即可

var xhr = createXHR();
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            alert(xhr.responseText);
        } else {
            alert("Request was unsuccessful : " + shr.status);
        }
    }
}
xhr.open("get","http://www.somewhere-else.com/page/", true);
xhr.send(null);

Preflighted Requests

CORS通过一种叫做Preflighted Requests的透明服务器验证机制支持开发人员使用自定义的头部、GET或POST之外的方法,以及不同类型的主题内同,在使用下列高级选项来发送请求时,就会向服务器发送一个Preflight请求,这种请求使用OPTIONS方法,发送以下头部

  • Origin:与简单的请求相同
  • Access-Control-Request-Method:请求自身使用的方法
  • Access-Control-Request-Headers:(可选)自定义的头部信息,多个头部以逗号隔开

Origin: http://www.nczonline.net
Access-Control-Request-Method:POST
Access-Control-Request-Headers:NCZ

发送请求后,服务器可以决定是否允许这种类型的请求,服务器通过在襄阳中发送如下头部与浏览器进行沟通

  • Access-Control-Allow-Origin:与简单请求相同
  • Access-Control-Allow-Method:允许的方法,多个方法用逗号隔开
  • Access-Control-Allow-Headers:允许的头部,多个头部用逗号隔开
  • Access-Control-Max-Age:应该将这个Prefilght请求缓存多长时间(以秒记)

Access-Control-Allow-Origin: http://www.nczonline.net
Access-Control-Allow-Method:POST, GET
Access-Control-Allow-Headers:NCZ
Access-Control-Max-Age:1728000

带凭据的请求

默认情况下,跨域请求不提供凭据(cookie,HTTP认证及客户端SSL证明等),通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据,如果服务器接受带平局的请求,会用下面的HTTP头部来响应
Access-Control-Allow-Credentials:true

跨浏览器的CORS

检查XHR是否支持CORS最简单的方法就是检查是否存在withCredentials属性,再结合检测XDR是否存在,就可以兼顾所有浏览器了

function createCORSRequest(method,url){
    var xhr = new XMLHttpRequest();
    //检查是否支持CORS
    if("withCredential" in xhr){
        xhr.open(method,url,true);
    } else if (typeof XDomainRequest != "undefined"){
        xhr = new XDomainRequest();
        xhr.open(method,url);
    } else {
        xhr = null;
    }
    return xhr
}

var request = createCORSRequest("get","http://www.somewhere-else.com/page/");
if(request){
    request.onload = function(){
        //对request.responseText进行处理
    }
    request.send();
}

xhr与xdr的共同属性/方法:

  • abort()
  • onerror()
  • onload()
  • responseText
  • send()
posted @ 2016-12-13 20:00  我这块臭狗石  阅读(257)  评论(0编辑  收藏  举报