经由过程XHR完成Ajax通讯的一个重要限定,来源于跨域平安战略。在默许情况下,Ajax只能接见与包括它的页面位于同一个域中的资本。然则偶然也须要一些跨域的要求。为了处置惩罚这个题目,如今的浏览器采纳CORS(Cross-Origin Resource Sharing,跨域资本共享)战略来完成。CORS是W3C的一个事情草案,定义了必需接见跨源资本时浏览器与服务器之间怎样举行沟通。这个战略的基本思想是运用自定义的HTTP头部让浏览器与服务器举行沟通,从而决议要求或相应的胜利和失利。注重要乞降相应都不包括cookie信息。
IE对CORS的完成
IE8中引入了XDR( XDomainRequest) 范例, 这个对象与XHR相似, 然则能完成平安可靠的跨域通讯。 XDR对象的平安机制部份完成了W3C的CORS范例。 以下是XDR与XHR的差别之处:
cookie不会随要求发送, 也不会随相应返回
只能设置要求头部信息中的Content – Type字段
不能接见相应头部信息
只支撑GET和POST要求
XDR对象运用要领: 建立一个实例, 挪用open要领, 挪用send要领。 open要领只吸收两个参数: 要求的范例和URL。 一切XDR的要求都是异步的。 要求返回后会触发load事宜, 相应数据保存在responseText属性中。
var xdr = new XDomainRequest();
xdr.onload = function() {
alert(xdr.responseText);
};
xdr.open("get", "http://www.somewhere-else.com/page/");
xdr.send(null);
在跨域要求上唯一能够获得相应的信息就是毛病本身, 因而肯定相应失利的体式格局就是运用onerror事宜。 要放到open之前运用。
xdr.onerror = function() {
alert("an error occurred!");
}
在要求返回之前, 能够挪用作废敕令abort() 要领:
xdr.abort(); //停止要求
与XHR一样, XDR对象也支撑timeout属性以及ontimeout事宜处置惩罚顺序。
xdr.timeout = 1000;
xdr.ontimeout = function() {
alert("late!")
}
将这些处置惩罚顺序添加到open之前才能够哦。
为了支撑post要求, XDR对象供应了contentType属性, 用来示意发送数据的花样: 在open以后, send之前设置
xdr.contentType = "application/x-www-form-urlencoded";
其他浏览器对CORS的完成
运用规范的XHR对象并在open()要领中传入相对URL即可:
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
document.getElementById("content").innerHTML = xhr.responseText;
} else {
console.log("error");
}
};
xhr.open("get", "http://www.somewhere-else.com/page/", true);
xhr.send();
其他的浏览器都经由过程XMLHttpRequest对象完成了对CORS的原生支撑。然则在跨域要求的时刻有以下的限定:
不能运用setRequestHeader()设置自定义头部。
不能吸收和发送cookie
挪用getAllResponseHeaders()要领总会返回空字符串。
无论是同源要求照样跨域要求,关于当地资本最好运用相对URL,在接见长途资本时再运用相对URL。
Preflighted Requests
通明服务器考证机制,支撑开发人员运用自定义的头部,get和post以外的要领,以及差别范例的主题内容。这类要求运用OPTIONS要领,发送以下头部:
Origin
:与简朴的要求雷同Access-Control-Request-Method
:要求本身运用的要领Access-Control-Request-Headers
:(可选)自定义头部信息,多喝头部逗号分开。
发送要求以后,服务器决议是不是许可这类范例的要求。服务器经由过程相应发送以下的头部与浏览器举行沟通:
Access-Control-Allow-Origin
:与简朴的要求雷同Access-Control-Allow-Methods
:许可的要领,多个要领以逗号分开Access-Control-Allow-Headers
:许可的头部,多个头部以逗号分开Access-Control-Max-Age
:应当将这个Preflight要求缓存多长时间(以秒示意)
带凭证的要求
经由过程将withCredentials
属性设置为true,能够指定特定的要求应当发送凭证。假如服务器吸收带凭证的要求,会用下面的HTTP头部相应
Access-Control-Allow-Credentials:true
跨浏览器的CORS
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://somewhere-else.com/page/");
if (request) {
request.onload = function() {
//request.responseText
};
request.send();
}