跨域的几种解决方案

参考文档:http://hi.baidu.com/xusx/blog/item/d7cda3c34d86a957b219a8d1.html

在实际的应用中,ajax对不同域下内容的访问有非常严格的限制,以下情况不允许访问:

  1. 不同域,包括二级域名。
  2. 不同端口。
  3. 不同协议。

通常的解决方案有以下几种:

script块

/*******

*jsLoader

*

*/

var Transfer={}

Transfer.Base = function() {}

Transfer.Base.prototype = {

  setOptions: function(options) {

    if(typeof options!="object"){options={};}

    this.options = {

        bCache:options.bCache||false,

        id:options.id||"scriptTemp",

        onfailure:options.onfailure||function(){},

        oncomplate:options.oncomplate||function(){}

    }

  }

}

/**

new Transfer.Request(url,{oncomplate:'',id:''})

*/

Transfer.Request=Class.create();

Transfer.Request.prototype=Object.extend(new Transfer.Base(),{

    initialize: function(url, options) {

    this.setOptions(options);

    this.request(url);

    },

    request:function(url){

        this.url=url;

        this.bCache=this.options.bCache;

        this.id=this.options.id;

        this.oncomplate=this.options.oncomplate;

        this.onfailure=this.options.onfailure;

        this.symbol="?";

        if(this.url.indexOf("?")!="-1")this.symbol="&";

        var head=document.getElementsByTagName("head")[0];

        var sT = $(this.id);

        if(sT&&sT.src&&sT.src==this.url){

            this.oncomplate();

            return;

        }

        if (sT) {sT.parentNode.removeChild(sT);}

        var s = document.createElement("script");

        head.appendChild(s);

        s.setAttribute("language", "javascript");

        s.setAttribute("type", "text/javascript");

        s.setAttribute("id", this.id);

        s.setAttribute("src", (this.bCache && this.bCache == true) ? this.url + this.symbol + Math.random() : this.url);

        var self=this;

        s.onload=s.onreadystatechange=function()

        {

            if (typeof ActiveXObject!="undefined") {

                if(s.readyState&&s.readyState=="loaded")self.oncomplate();

                if(s.readyState&&s.readyState=="complete")return;

            }else{

                self.oncomplate();

            }

        }

        s.onerror=function(){ //ie not work

            if(s&&s.parentNode)s.parentNode.removeChild(s);

            self.onfailure();

            throw new Error("connect faild,please try later;");

        }

     }

});

/****jsLoader end****/

 

document.domain

 

当主域、协议、端口相同时,通过设置页面的document.domain主域,Javascript可以在不同的子域名间访问控制,比如通过设置 document.domain=’dancewithnet.com’,http://dancewithnet.com和http: //lab.dancewithnet.com页面可互访,这个特性也提供了此情况下不同子域名下的XMLHTTPRequest相互访问的解决方案。

对于主域、协议、端口相同时的Ajax跨域问题,很早就有设置document.domain来解决的说法,但一直没有看到具体的成功应用,这几天尝试了一下,其原理就是,利用一个隐藏的iframe引入所跨另一子域的页面作为代理,通过Javascript来控制iframe引入的另一子域的 XMLHTTPRequest来进行数据获取。

例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>用document.domain解决Ajax跨域</title></head> <body><iframe src="http://lab.dancewithnet.com/2007/07/solve-cross-domain-ajax-with-document-domain/proxy.html" id="proxy"></iframe>

<script type="text/javascript" src="http://dancewithnet.com/lab/yui/yahoo-dom-event.js"></script><script type="text/javascript" src="http://dancewithnet.com/lab/yui/connection.js"></script>

<script type="text/javascript">//<![CDATA[document.domain = 'dancewithnet.com';var $D = YAHOO.util.Dom;var $ = $D.get;var $E = YAHOO.util.Event;var $C = YAHOO.util.Connect;$E.on('btn1','click',getContent1);

var getContent2 = function(){ var sUrl = 'http://lab.dancewithnet.com/eg.txt'; var proxy = $('proxy').contentWindow; var proxy$C = proxy.YAHOO.util.Connect; var request = proxy$C.asyncRequest('GET',sUrl,{ success:function(o){ $('content2').innerHTML = o.responseText; }, failure:function(){} });}$E.on('btn2','click',getContent2);//]]></script> </body> </html>

 

后台代理方式

 

对于不同主域/不同协议/不同端口下的Ajax访问需要通过后台的代理来实现,更多细节可以看看Use a Web Proxy for Cross-Domain XMLHttpRequest CallsFixing AJAX: XMLHttpRequest Considered Harmful。”

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

转:

 好久没写文章了,不过中午看了一篇关于“用document.domain解决Ajax跨子域”的文章后,心里的一个结差不多解开了,索性也就此总结一下。

         以前做网站的时候,遇到跨站(域)调用文章的问题,那时候没想到什么好方法,一般用iframe、Javascript文件调用或手动添加l链接,由于这些跨站调用的内容不多又不经常,所以也没大放在心里。尽管碰到网上不少的“小偷程序”和“采集程序”,但也没去多想什么。

         现在,大量跨站(域)调用内容的情形总算遇到了,得想个高明些的办法,毕竟时代不同了。

         于是到书上或google上学xml,xmlhttp,ajax,由于时间有限,囫囵吞枣,几经周折,最终发现实现的方法并不高明,效率当然也不高。

         今天中午吃晚饭,上蓝色理想,没想碰到“随网之舞”(http://dancewithnet.com/)里的一篇“用document.domain解决Ajax跨子域”,顺便摘抄如下:

“因为浏览器的安全策略,浏览器不允许不同域(比如:dancewithnet.com和lab.dancewithnet.com)、不同协议(比如:http://dancewithnet.com和https://dancewithnet.com)、不同端口(比如:http:dancewithnet.com和http://dancewithnet.com:8080)下的页面通过XMLHTTPRequest相互访问,这个问题同样影响着不同页面的Javascript的相互调用和控制,但是当主域、协议、端口相同时,通过设置页面的document.domain主域,Javascript可以在不同的子域名间访问控制,比如通过设置document.domain=’dancewithnet.com’,http://dancewithnet.com和http://lab.dancewithnet.com页面可互访,这个特性也提供了此情况下不同子域名下的XMLHTTPRequest相互访问的解决方案。

“对于主域、协议、端口相同时的Ajax跨域问题,很早就有设置document.domain来解决的说法,但一直没有看到具体的成功应用,这几天尝试了一下,其原理就是,利用一个隐藏的iframe引入所跨另一子域的页面作为代理,通过Javascript来控制iframe引入的另一子域的XMLHTTPRequest来进行数据获取。请看实例>>

“对于不同主域/不同协议/不同端口下的Ajax访问需要通过后台的代理来实现,更多细节可以看看Use a Web Proxy for Cross-Domain XMLHttpRequest CallsFixing AJAX: XMLHttpRequest Considered Harmful。”

           我想这是一个不错的想法,所以也想尝试一下,至于具体过程,等到有空再写吧。

 

第一种方法的例子:

 var Transfer={};
        Transfer.Base = function() {};
        Transfer.Base.prototype = {
            setOptions: function(options) {
                if(typeof options!="object"){
                    options={};
                };
                this.options = {
                    bCache:options.bCache||false,
                    id:options.id||"scriptTemp",
                    onfailure:options.onfailure||function(){},
                    oncomplate:options.oncomplate||function(){}
                }
            }
        };

//propotype.js
        var Class = {
            create: function() {
                return function() {
                    this.initialize.apply(this, arguments);
                }
            }
        };
        Object.extend = function(destination, source) {
            for (var property in source) {
                destination[property] = source[property];
            }
            return destination;
        };

        Transfer.Request=Class.create();
        Transfer.Request.prototype=Object.extend(new Transfer.Base(),{
            initialize: function(url, options) {
                this.setOptions(options);
                this.request(url);
            },
            request:function(url){
                this.url=url;
                this.bCache=this.options.bCache;


                this.id=this.options.id;

//传入的方法名
                this.oncomplate=this.options.oncomplate;
                this.onfailure=this.options.onfailure;
                this.symbol="?";
                if(this.url.indexOf("?")!="-1")this.symbol="&";
                var head=document.getElementsByTagName("head")[0];
                var sT = document.getElementById(this.id);
                if(sT&&sT.src&&sT.src==this.url){
                    this.oncomplate();
                    return;
                }
                if (sT) {
                    sT.parentNode.removeChild(sT);
                }

//构建<script id="传入id" type="text/javascript" src="传入的url">
                var s = document.createElement("script");
                head.appendChild(s);
                s.setAttribute("language", "javascript");
                s.setAttribute("type", "text/javascript");
                s.setAttribute("id", this.id);
                s.setAttribute("src", (this.bCache && this.bCache == true) ? this.url + this.symbol + Math.random() : this.url);
                var self=this;
                s.onload=s.onreadystatechange=function()
                {
                    if (typeof ActiveXObject!="undefined") {

//加载成功启动 传入的方法 被加载的对象 

             if(s.readyState&&s.readyState=="loaded")self.oncomplate();//调用函数
                        if(s.readyState&&s.readyState=="complete")return;
                    }else{
                        self.oncomplate();
                    }
                }
                s.onerror=function(){ //ie not work
                    s.parentNode.removeChild(s);
                    self.onfailure();
                    throw new Error("some error occurd,please try again later");
                }
            }
        });

页面调用:

function transfers(){

if('<%=searchType%>'=='行车路线'){

new Transfer.Request("&destLatLon=< DLatAndDLon>http://mapx.mapbar.com/json/getDriveByNid.jsp?origLatLon=<%=DLatAndDLon1%>&destLatLon=<%=DLatAndDLon2%>",{

                    oncomplate:getDrive,

                    id:'drive'

                    });

                    }else{

                   

new Transfer.Request("&origLatLon=< DLatAndDLon>&destLatLon=<%=DLatAndDLon2%">http://mapx.mapbar.com/json/getBusByNid.jsp?city=<%=strCity%>&origLatLon=<%=DLatAndDLon1%>&destLatLon=<%=DLatAndDLon2%

>",{

                    oncomplate:getBus,

                    id:'busResult'

                    });

              

              

               }

 }

  function getDrive(){

   

    alert(drive);//drive为调用另一个域返回的对象

   

    var routes="共"+drive.routes.count+"个步骤";

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值