《JavaScript高级程序设计》读书笔记21.4跨域资源共享

默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。

CORS(Cross-Origin Resource Sharing,跨源资源共享)是W3C的一个工作草案,定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通。

CORS的 基本思想,就是使用自定义的 HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

1. IE对CORS的实现

  • 引入了 XDR(XDomainRequest)类型,与XHR类似,但有4点不同
  1. cookie不会随请求发送,也不会随响应返回。
  2. 只能设置请求头部信息中的 Content-Type 字段。
  3. 不能访问响应头部信息。
  4. 只支持 GET 和 POST 请求。
    这些变化使 CSRF(Cross-Site Request Forgery,跨站点请求伪造)和 XSS(Cross-Site Scripting,跨
    站点脚本)的问题得到了缓解。
  • 使用方法:创建一个XDomainRequest的实例,调用open()方法,再调用 send()方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var xdr = new XDomainRequest(); 
    xdr.onload = function(){
    alert(xdr.responseText);
    };
    xdr.onerror = function(){
    alert("An error occurred.");
    };
    xdr.open("get", "http://www.somewhere-else.com/page/");
    xdr.send(null);
  • 为支持 POST 请求,XDR对象提供了 contentType属性,用来表示发送数据的格式,如下面的例子所示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var xdr = new XDomainRequest(); 
    xdr.onload = function(){
    alert(xdr.responseText);
    };
    xdr.onerror = function(){
    alert("An error occurred.");
    };
    xdr.open("post", "http://www.somewhere-else.com/page/");
    xdr.contentType = "application/x-www-form-urlencoded";
    xdr.send("name1=value1&name2=value2");

2.其他浏览器对CORS的实现

  • 请求位于另一个域中的资源,使用标准的XHR对象并在open()方法中传入绝对URL即可。
  • 跨域的限制:
  1. 不能使用setRequestHeader()设置自定义头部。
  2. 不能发送和接收 cookie。
  3. 调用 getAllResponseHeaders()方法总会返回空字符串。
  • 对于本地资源,最好使用相对 URL,在访
    问远程资源时再使用绝对 URL

3. Preflighted Reqeusts

IE10及以前都不支持

4. 带凭据的请求

IE10及以前都不支持

5. 跨浏览器的CORS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function createCORSRequest(method, url){  
var xhr = new XMLHttpRequest();
if ("withCredentials" 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();
}
liborn wechat
欢迎您扫一扫上面的微信二维码,订阅我的公众号!