论坛首页 Web前端技术论坛

求XmlHttp 跨域的解决方案

浏览 67813 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-08-30  
需求: 访问指定外网路径的数据,但该路径首次访问会报告500错误,刷新就可以,通过察看http头发现首次访问激活session,然后第二次访问方才正常。

使用xmlhttp 可以解决此需求,先用xmlhttp 访问一次,在回调再使用 location.replace(url) 。于是不可避免的遭遇"权限禁止"错误。

为了实现 xmlhttp 跨域访问(当然是在不修改默认权限设置的要求下),我尝试了不少方法:

1. 有人说apache 的 mod_rewrite 可以解决问题,我没有使用apache,于是在tomcat中使用 UrlRewriteFilter(http://tuckey.org/urlrewrite/)。当跨域访问的时候,确实是不再报告权限错误,然后仍然会报告无法访问。ie 和 firefox 都是如此。mod_rewrite 和 UrlRewriteFilter 我想机制应该是一样的,后来仔细看了该文:http://www.livejournal.com/users/premshree/2005/04/20/ ,发现mod_rewrite 大概支持自动代理,所以也许可以解决问题。但不能强求都用apache吧?

2.  xmlhttp 不行,我于是使用传统的iframe的方法,即动态创建一个iframe,然后设置onload事件来callback。firefox 一切正常,然而ie却有问题,透过研究http 头,发现iframe 访问后成功激活session,  父窗口再访问时firefox正确传递了cookie,而ie却没有。

dlee说过,设置一个代理可以解决跨域的问题,愿闻其详。
   发表时间:2005-08-30  
自己回答吧

测试了apache的mod_rewrite,确实解决了问题,不过图片无法正常显示。

使用的是apache for win32, 版本 2.0.54。
1 请登录后投票
   发表时间:2005-08-31  
醒来 写道
测试了apache的mod_rewrite,确实解决了问题,不过图片无法正常显示。

不要使用 mod_rewrite,mod_rewrite 的性能很差的。
醒来 写道
dlee说过,设置一个代理可以解决跨域的问题,愿闻其详。

这个方法也是从别人那里偷学来的。
http://stuff.rancidbacon.com/gmaps-standalone/
就是在浏览器端使用 Proxy 模式将 XMLHTTP 做一下封装,跨域的请求同样发送到服务器端,由服务器端的代理来请求相应的数据,然后发送给浏览器端。这样实际上浏览器端的所有请求都是发到相同的域,在服务器端代理的帮助下,实现了跨域的能力。
附件是浏览器端和服务器端的代码。

另外这里还有一个方法,感兴趣的话研究一下,我们来讨论讨论。
http://johnvey.com/features/deliciousdirector/
2 请登录后投票
   发表时间:2005-08-31  
十分感谢!

dlee 写道

就是在浏览器端使用 Proxy 模式将 XMLHTTP 做一下封装,跨域的请求同样发送到服务器端,由服务器端的代理来请求相应的数据,然后发送给浏览器端。这样实际上浏览器端的所有请求都是发到相同的域,在服务器端代理的帮助下,实现了跨域的能力。


以前测试过服务器代理的方式,是可以跨域获取数据,但是无法维护session状态,解决不了前文中我所说的需求。mod_rewrite 是可以的,它的代理机制不是很清楚,但相信做了一番处理。

dlee 写道

另外这里还有一个方法,感兴趣的话研究一下,我们来讨论讨论。
http://johnvey.com/features/deliciousdirector/


正在研究中。。。
0 请登录后投票
   发表时间:2005-09-02  
dlee 写道

另外这里还有一个方法,感兴趣的话研究一下,我们来讨论讨论。
http://johnvey.com/features/deliciousdirector/


事实上,该项目关于xmlhttp跨域访问的说明文章url 如下:
http://johnvey.com/features/deliciousdirector/web-service-broker.html

但很遗憾,它并没有提供能解决我的需求的的方案。

该文提到的设置 document.domain 的方式只适用于两主机在同一个父域的情况。

看样子,就目前我了解的结果, 结论如下:

1.  如果两主机属于同一个父域,采用设置document.domain 的方法。
2.  如果只是简单的跨域获取数据,可以使用类似dlee提供的附件中的代理。
3.  如果需要跨域提交数据(比如登录),成本最低的方式就是使用apache的mod_rewrite。
0 请登录后投票
   发表时间:2005-09-02  
醒来 写道
2. 如果只是简单的跨域获取数据,可以使用类似dlee提供的附件中的代理。
3. 如果需要跨域提交数据(比如登录),成本最低的方式就是使用apache的mod_rewrite。

我想 IFrame 可以同时做到跨域的获取和提交数据,我们可以将数据传输方法(XMLHTTP or IFrame)完全封装起来,高层完全不需要关心这些细节。不过这个想法需要经过进一步实践的验证,似乎使用 IFrame 同样也有一些出于安全考虑的限制,否则就容易被黑客利用来损害用户的利益了。

这个讨论我们还会继续。
0 请登录后投票
   发表时间:2005-09-04  
dlee 写道
醒来 写道
2. 如果只是简单的跨域获取数据,可以使用类似dlee提供的附件中的代理。
3. 如果需要跨域提交数据(比如登录),成本最低的方式就是使用apache的mod_rewrite。

我想 IFrame 可以同时做到跨域的获取和提交数据,我们可以将数据传输方法(XMLHTTP or IFrame)完全封装起来,高层完全不需要关心这些细节。不过这个想法需要经过进一步实践的验证,似乎使用 IFrame 同样也有一些出于安全考虑的限制,否则就容易被黑客利用来损害用户的利益了。

这个讨我们还会继续。


在我的英文版XP sp2, ie版本号6.0.2900.2180 上,我测试过了,iframe是可以跨域获取和提交数据,但有一点遗憾,就是不能维护session状态,但firefox(v1.0.6)是可以的。
0 请登录后投票
   发表时间:2006-12-02  
iframe确实是可以实现跨域提交数据,但是获取数据可以做,最多可以让你想要的数据下载到浏览器中,但你事实上并不可访问这种数据
因为没法处理回调函数,iframe取得的数据只能存在于iframe中,iframe中的数据在跨域的情况下,与父页面是不可相互访问

最近一个项目必须在跨域环境下操作,iframe、xmlhttp都无能为力,唯一可和的方案是使用script标签来提交加载数据
服务器端处理请求后返回的数据格式化为callBack(JSON )的格式
json是什么,在这里不多说,callBack是一个自定义的回调函数,名字可自行设置

function scriptServerCall(url){
     var script=document.createElementScript("script");
     script.setAttribute("src",url);
     document.body.appendChild(script);
}

scriptServerCall_callback(retValue){
         alert("服务器端返回数据是:"+retValue);
}

服务器端返回
scriptServerCall_callback("scriptServerCall Test");
0 请登录后投票
   发表时间:2006-12-03  
json也不太爽

一个设想:flash加载其他域下的东西方便不?
0 请登录后投票
   发表时间:2006-12-04  
xmldom也行,在ie和非ie下处理方式不同
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics