跨源资源共享 (CORS) 是一个 W3C 工作草案,它定义了浏览器和服务器在跨源访问资源时必须如何通信。 CORS 背后的基本思想是使用自定义 HTTP 标头来允许浏览器和服务器充分了解彼此,以确定请求或响应是成功还是失败。
对于一个简单的请求,即使用 GET 或 POST 且没有自定义标头且正文为 text/plain 的请求,发送的请求带有一个名为 Origin 的额外标头。 Origin 标头包含请求页面的来源(协议、域名和端口),以便服务器可以轻松确定是否应该提供响应。示例 Origin 标头可能如下所示:
Origin: http://www.webiste.com
如果服务器决定允许该请求,它会发送一个 Access-Control-Allow-Origin 标头来回显发送的相同来源,如果它是公共资源,则返回“*”。例如:
Access-Control-Allow-Origin: http://www.webiste.com
如果缺少此标头,或者来源不匹配,则浏览器将拒绝该请求。如果一切正常,则浏览器会处理该请求。请注意,请求和响应都不包含 cookie 信息。
前面提到的所有浏览器都支持这些简单的请求。 Firefox 3.5+、Safari 4+ 和 Chrome 都支持通过 XMLHttpRequest 对象使用。当尝试打开不同来源的资源时,此行为会自动触发,无需任何额外代码。例如:
var xhr = new XMLHttpRequest();
xhr.open("get", "http://www.webiste.com/some_resource/", true);
xhr.onload = function(){ //instead of onreadystatechange
//do something
};
xhr.send(null);
要在 Internet Explorer 8 中执行相同操作,您需要以相同的方式使用 XDomainRequest 对象:
var xdr = new XDomainRequest();
xdr.open("get", "http://www.webiste.com/some_resource/");
xdr.onload = function(){
//do something
};
xdr.send();
Mozilla 团队在他们关于 CORS 的帖子中建议您应该检查 withCredentials 属性是否存在,以确定浏览器是否通过 XHR 支持 CORS。然后你可以结合 XDomainRequest 对象的存在来覆盖所有浏览器:
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.webiste.com/");
if (request){
request.onload = function(){
//do something with request.responseText
};
request.send();
}
Firefox、Safari 和 Chrome 中的 XMLHttpRequest 对象与 IE 中的 XDomainRequest 对象具有足够相似的接口,因此该模式运行良好。常用的接口属性/方法有:
- abort() - 用于停止已经在进行的请求。
- onerror - 使用而不是 onreadystatechange 来检测错误。
- onload - 使用而不是 onreadystatechange 来检测成功。
- responseText - 用于获取响应内容。
- send() – 用于发送请求。