同源策略是对XHR的一个主要约束,它为通信设置了“相同的域、相同的端口、相同的协议”这一限制。跨域解决方案如下:
一、CORS(cross-origin Resource Sharing )跨域资源共享
CORS定义了在需要跨域资源时,浏览器与服务器如何沟通。基本思想:使用自定义HTTP头部让浏览器与服务器进行沟通,从而决定请求或相应是应该成功,还是应该失败。
例如get或post请求,发送请求时添加额外的Origin头部,其中包含请求页面的源信息(协议、域名、端口)以便服务根据这个头部信息来决定是否给予响应。
下面是一个Orign头部的示例:
Origin:http://www.nczonline.net
若果服务器认为这个请求可以接受,就在Access-Content-Allow-Origin头部中回发相同的源信息(如果是公共资源,可以回发*“”)。例如:
Access-Content-Allow-Origin:http://www.nczonline.net
如果没有这个头部信息,或者有这个头部信息但源信息不匹配,浏览器就会驳回请求。正常情况下,浏览器会处理请求。
注意:请求与响应中都不包含cookie信息。
跨浏览器的CORS
/**
*获得所有浏览器都支持的跨域请求对象
*/
function createCORSRequest(method,url){
var xhr = new XMLHTTPRequest();
if("withCredentials" in xhr){
// Firefox3.5+、safari4+、chrome
xhr.open(method,url,true);
}else if(typeof XDomainRequest!=undefined){
// IE10及更早的版本
xhr = new XDomainRequest();
xhr.open(method,url);
}else{
xhr=null;
}
return null;
}
// 获得不同浏览器对跨域请求支持的对象
var request = createCORSRequest("get","http://www.somewhere-else.com/page/");
if(request){
request.οnlοad=function(){
//对request.responseText进行处理
};
request.send(null);
}
XDomainRequest 仅有有限的几个方法供我们来调用,支持少数事件但足够。
1、仅只是 GET 和 POST 两个方法。/
2、支持的事件有:onerror,onload,onprogress,ontimeout
3、提供的方法:abort,open,send
4、提供的属性:contentType, responseText,timeout
二、其他跨域技术
(1)、图像ping
动态创建图像经常用于图像ping。图像ping是与服务器进行简单、单向跨域请求的一种方式。请求的数据是通过查询字符串形式发送的,而响应可是是任意内容,但通常是像素图或204响应。通过图像ping,浏览器得不到任何具体的数据,但是通过侦听load和error事件,它能够知道响应是何时接收到的。
来看下面的例子:
// 创建一个Image实例
var img = new Image();
//当请求完成,回调的函数
img.load=img.error=function(){
alert("done");
};
// 发送name参数到服务器
img.src="http://www.example.com/test?name=Nicy";
图像Ping最常用于用户动态点击页面或动态广告曝光次数。图像Ping只能用于浏览器与服务器的单向通信。
图像Ping有两个主要的缺点:
1)、只能发送get请求;
2)、无法访问服务器的响应文本;
(2)JSONP
JSONP是JSON with padding(填充式JSON或参数式json)
JSONP是通过动态<script>元素来使用的,使用时可以为src指定一个跨域的URL。
来看下例子:
// 获得响应内容,请求完成后,会立即执行
function handleResponse(response){
// 查询地理定位服务来显示IP地址和位置信息
//alert(response.id+"--"+response.city);
}
/**
var script = document.createElement("script");
script.src="http://freegeip.net/json/?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);
*/
JSONP的优点:
1)、直接访问响应文本,可以实现浏览器与服务器的双向通信;
2)、要确定JSONP请求是否失败。HTML5给<script>元素新增了一个onerror事情处理程序
JSONP的缺点:
1)、JSONP是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了放弃JSONP调用之外,没有办法追究。