闭关纪要2.不同子域名之间Ajax访问跨域问题的解决

        上次给我的闭关纪要开了一个头之后,我就一直继续闭关研究,虽然我研究的东西大多很有来头,而且我也预计将源码公开,可是都还没有一个完整的东西来给大家介绍,几天前,我在解决我的网站性能问题的时候突然有一个想法,能够解决我一直很想解决的子域名跨域的问题,觉得应该与大家分享一下,不知道有没有人用过。

        问题描述如下:我个人使用Ajax的方式通常是调用类似Json或者Rest接口,这些接口都是通过Script标签传递数据,不过这样使用的问题在于只能通过异步来加载数据,很多时候会造成程序架构上的不便,远不如直接使用Xml或者文本文件的同步访问模式(XML Http Request)来的直接,可是如果用XML Http Request的模式,就会产生跨域问题,这样,必须要把页面和XML服务部署在同一个域名上,哪怕是同一个域名的子域名也不行。

        假如我希望通过Ajax的模式,由http://www.dituren.cn/ 页面上的代码去访问http://51ditu.dituren.cn/  上面的XML或者文本服务,有办法实现么?

        或许你认为通过页面上设置document.domain可以解决,不过这是白费心机,我已经研究过了,这样是行不通的!在HTML页面上为什么可以呢?因为两个页面都可以这样设置域名:document.domain='dituren.cn';这样他们就是在同一个域了,可是页面去访问XML的时候,XML显然没有设置自己的domain的地方,因此就会产生跨域访问,用户得到一个“没有权限”的提示。

        既然是这样,那么我想,为什么不在http://51ditu.dituren.cn/  上面使用一个代理页面,设置自身的document.domain='dituren.cn',而www域下的网页通过Iframe加载这个页面,并且也设置自己的域,这样的话,这两个页面之间的交流是畅通的,而这个代理页面本身是在51ditu域下的,因此肯定可以访问本域的XML服务了。

        以上想法经过我的测试(IE6,IE7,FF3),完全可用!因此假如您已经理解我的意思,或者暂时不需要此技巧,可以不再向下看了,假如您想参考我的具体使用方法,可以向下看,说不定能对您有所启发。

        先看看代理页面的代码吧:

 

 1 < html >
 2 < head >
 3 ExpandedBlockStart.gifContractedBlock.gif < script  language ="javascript" >
 4    //本函数在页面加载的时候运行
 5    function onLoad()
 6ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 7        document.domain="dituren.cn"//设置自身的域
 8        var hash=location.hash;//父窗口会使用锚点参数传递一个回调函数名称过来
 9        if(hash&&hash.length>1)//如果回调函数名称存在
10ExpandedSubBlockStart.gifContractedSubBlock.gif        {
11            hash=hash.substring(1);
12            parent[hash](self);//调用回调函数,通知父窗口代理已经准备好了
13        }

14    }

15    //本函数会由父窗口调用,返回一个XMLHttpRequest对象给父窗口,剩下的操作父窗口自己完成
16    function createHttpRequest()
17ExpandedSubBlockStart.gifContractedSubBlock.gif    {
18        if(window.XMLHttpRequest)
19ExpandedSubBlockStart.gifContractedSubBlock.gif        {
20            return new XMLHttpRequest();
21        }

22        else if(typeof(ActiveXObject)!="undefined")
23ExpandedSubBlockStart.gifContractedSubBlock.gif        {
24            return new ActiveXObject("Microsoft.XMLHTTP");
25        }

26    }

27
</ script >
28 </ head >
29 < body  onload ="onLoad()" ></ body >
30 </ html >

 

        代码不算复杂吧,这是一个静态文件现在被我部署到了http://51ditu.dituren.cn/51ditu/ajaxAgent.htm ,我的其它子域页面上假如需要调用http://51ditu.dituren.cn/ 上面的服务,可以采用类似于以下代码:

 

 1 ExpandedBlockStart.gif ContractedBlock.gif         window.onAgentLoaded = function (win) {window.agentWindow=win;} // 设置回调函数,在被agent页面回调的时候设置window.agentWindow变量
 2         document.domain = " dituren.cn " ; // 设置自己的域
 3         document.write( ' <iframe src="http://51ditu.dituren.cn/51ditu/ajaxAgent.htm#K_CPoint_AgentLoaded" style="display:none;"></iframe> ' ); // 在页面上通过Ajax加载Agent并通过锚点将回调函数名称提供给Agent页面
 4
 5          // 页面上的其它程序通过调用此函数来获得访问ajax的request对象
 6          function  createHttpRequest()
 7 ExpandedBlockStart.gifContractedBlock.gif         {
 8ExpandedSubBlockStart.gifContractedSubBlock.gif            if(window.agentWindow){return window.agentWindow.createHttpRequest();}
 9            else
10ExpandedSubBlockStart.gifContractedSubBlock.gif            {
11            //假如调用服务的时候AjaxAgent还没有加载完成,这个时候怎么办?
12            //我的逻辑是调用本域的,因为我的服务在每个域都有部署,只是为了性能才需要调用其它域的(另外的服务器)
13            }

14        }

 

        上面的代码已经获取了一个HttpRequest对象,怎么使用就不用我在这里说明了,总之用这个方法实现了跨子域名的Ajax访问,这是我最高兴的。

        一直以来,我都希望能够将我的页面部署在一个很稳定的服务器,而将一些附加的服务部署在另一个地方,因为这些附加的服务有些是很耗性能的,避免对主页面服务器产生比较大的影响,这次通过这个方法,我终于可以做到这个了。

        这次网站从http://www.step1.cn/ 迁移到http://www.dituren.cn/ 一个很重要的事情就是域名的分拆,以前将很多的内容都部署在一个www域名下,现在,被我拆成了很多子域名,在后面,我会逐次的提到每个域名的作用和相关的核心技术。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值