首页 > 代码库 > 解决浏览器跨域问题

解决浏览器跨域问题

最近在做项目过程中遇到客户端访问不同域的服务时,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库有冲突。

解决浏览器跨域问题