首页 > 代码库 > 解决浏览器跨域问题
解决浏览器跨域问题
最近在做项目过程中遇到客户端访问不同域的服务时,IE10以下的版本不会发起http请求(google和火狐内置支持跨域)。
这是为了对跨站点请求伪造攻击采取的安全措施。如果我们需要跨域访问,那该怎么办那?
不用怕IE还是给我们提供了一个解决方法。在IE8以后,它提供了一个XDomainRequest 对象(详细内容请看http://msdn.microsoft.com/en-us/library/cc288060(VS.85).aspx),它是专门跨站数据获取的对象,它里面有两个比较重要的方法:open、send。
Open是连接服务器,打开跨域请求,而send是发送参数字符串到服务器。
下面是一个利用XDomainRequest 对象跨域访问的js脚本。
transport = function () {
var verb = function () {
var post = "POST";
var get = "GET";
var put = "PUT";
var del = "DELETE";
return {
post: post,
get: get,
put: put,
del: del
};
}();
var executeRequest = function (
method,
url,
data,
doneCallback,
failCallback) {
var isCrossDomainRequest = url.indexOf(‘http://‘) == 0
|| url.indexOf(‘https://‘) == 0;
if (window.XDomainRequest
&& isCrossDomainRequest) {
var xdr = new XDomainRequest();
if (xdr) {
xdr.open(method, url);
xdr.onload = function() {
var result = $.parseJSON(xdr.responseText);
if (result === null
|| typeof(result) === ‘undefined‘) {
result = $.parseJSON(
data.firstChild.textContent);
}
if ($.isFunction(doneCallback)) {
doneCallback(result);
}
};
xdr.onerror = function() {
if ($.isFunction(failCallback)) {
failCallback();
}
};
xdr.onprogress = function() {};
xdr.send(data);
}
return xdr;
} else {
var request = $.ajax({
type: method,
url: url,
data: data,
dataType: "JSON",
contentType: ‘application/json‘
}).done(function (result) {
if($.isFunction(doneCallback)) {
doneCallback(result);
}
}).fail(function (jqXhr, textStatus) {
if($.isFunction(failCallback)) {
failCallback(jqXhr, textStatus);
}
});
return request;
}
};
return {
verb: verb,
executeRequest: executeRequest
};
}();
根据以下方法进行访问:
Get 请求:
transport.executeRequest(
transport.verb.get,
url,
null,//这里是传递参数
function(result) {
//可以在这里操作返回的数据
},
function(jqXhr, textStatus) {
// 请求失败之后可以在这里进行相应操作。
}
Post请求:
transport.executeRequest(
transport.verb.post,
url,
null,//这里是传递参数
function(result) {
//可以在这里操作返回的数据
},
function(jqXhr, textStatus) {
// 请求失败之后可以在这里进行相应操作。
}
但是这个方法在传递参数的时候不能传递对象参数(如:{brbh:1,jlid:2}),只能传递字符串参数(brbh=1&jlid=2)。
还有一种解决方案,就是更改jQuery库的请求方式:
(function (jQuery) {
//创建连接对象,为了向后兼容,仍然使用ajaxSettings
jQuery.ajaxSettings.xdr = function () {
return (window.XDomainRequest ? new window.XDomainRequest() : null);
};
// 确定支持的属性
(function (xdr) {
jQuery.extend(jQuery.support, { iecors: !!xdr });
})(jQuery.ajaxSettings.xdr());
// 如果浏览器支持XDomainRequest,则创建传输
if (jQuery.support.iecors) {
jQuery.ajaxTransport(function (s) {
var callback,
xdr = s.xdr();
return {
send: function (headers, complete) {
xdr.onload = function () {
var headers = { ‘Content-Type‘: xdr.contentType };
complete(200, ‘OK‘, { text: xdr.responseText }, headers);
};
// 自定义字段
if (s.xhrFields) {
xhr.onerror = s.xhrFields.error;
xhr.ontimeout = s.xhrFields.timeout;
}
xdr.open(s.type, s.url);
xdr.send((s.hasContent && s.data) || null);
},
abort: function () {
xdr.abort();
}
};
});
}
})(jQuery);
这种方法比前一种好用,只需在引入jQuery库后,添加该段脚本,就可以使用jQuery.ajax去访问。如:
$.ajax({
type: "get",
contentType: "text/palin",
dataType: "json",
url:”http://www.baidu.com”,
success: function (data) {
alert(data.length);
}
});
我个人在使用过程中没发现与原来的jquery库有冲突。
解决浏览器跨域问题