您的位置:首页 > 其它

Ajax跨域问题解决方案

2010-05-20 10:18 621 查看
由于安全问题的考虑,Ajax(xmlhttprequest)默认是不支持跨域调用的。比如在www.cadal.com去请求www.test.cadal.com的数据,都是不行的。

解决方案有很多,总结如下:

参考:

1.利用<script>标签

Difficult to know when the content is available, no standard methodology, can be considered a "security risk".

script设置Url后自动会执行

example

远端:

var data=123;


客户端:

<html>
<body>
<mce:script id="test"></mce:script>
<input type="button" id="button" value="获取" onclick="get('http://test.cadal.com/demo/test.asp');">
<mce:script type="text/javascript"><!--

function get(url)
{
document.getElementById("test").src=url;
alert(data);
}
// --></mce:script>
</body>
</html>


2.代理

Local proxy:
Needs infrastructure (can't run a serverless client) and you get double-taxed on bandwidth and latency (remote - proxy - client).

利用如动态网页ASP JSP PHP等进行代理,进行中转,缺点显而易见。

3.frame方法

在同一个域下的各个子域之间(非完全跨域),如果设置了document.domain,那么是可以相互之间调用js的。。利用这一点,可以在test.zzsky.cn下面放上一个页面,这个页面可以完成用ajax获取同一个子域www.test.cadal.com的数据,而在 www.cadal.com下框架这个页,这样就可以操纵被框架页来获取数据了。

example

远端frame:

<html>
<head>
<mce:script type="text/javascript" src="http://www.cadal.com/demo/ajax-cross-domain/Ajax.js" mce_src="http://www.cadal.com/demo/ajax-cross-domain/Ajax.js"></mce:script>
<mce:script type="text/javascript"><!--

document.domain="cadal.com";
// --></mce:script>
</head>
<body>
</body>
</html>


客户端:

<html>
<head>
<mce:script type="text/javascript"><!--

document.domain="cadal.com";
// --></mce:script>
<body>
<iframe src="http://test.cadal.com/demo/iframe.htm" mce_src="http://test.cadal.com/demo/iframe.htm" id="proxy"></iframe>
<mce:script type="text/javascript" src="http://www.cadal.com/demo/ajax-cross-domain/Ajax.js" mce_src="http://www.cadal.com/demo/ajax-cross-domain/Ajax.js"></mce:script>
<input type="button" id="button" value="获取" onclick="get('http://test.cadal.com/demo/test.asp');">
<mce:script type="text/javascript"><!--

function get(url)
{
var proxy=document.getElementById("proxy").contentWindow;
proxy.createRequestObject(url,out)
}

function out(str)
{
alert(str);
}
// --></mce:script>
</body>
</html>


附:跨子域设置的规则:当两个二级域名、URL协议、端口都相同的网页,自身都通过JavaScript设置了相同的document.domain值,并且此值至少等于自身的二级域名,它们之间才可以相互作用。

4.对于Flash

Remote host needs to deploy a crossdomain.xml file, Flash is relatively proprietary and opaque to use, requires learning a one-off moving target programming langage.

Flash也同样出于安全考虑,存在跨域问题,可以通过在远端设置crossdomain.xml解决(貌似比较困难),也可以通LCDS设置代理访问解决这个问题。

5.JSONP技术

JSON with padding. JQuery1.2以后支持JSONP的应用,具体的函数是getJSON,调用方法如下:

JQuery官方的例子是调用Flickr的接口

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?",
function(data){
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});


其他没有什么大问题,关键是远端接口应该写点什么内容呢?

jsoncallback=?是关键的所在!其中"?"符号会被Query自动替换成其他的回调方法的名称,具体过程和原理我们这里不理会。我们关心的是jsoncallback=?起什么作用了?原来jsoncallback=?被替换后,会把方法名称传给服务器。我们在服务器端要做什么工作呢?服务器要接受参数jsoncallback,然后把jsoncallback的值作为JSON数据方法名称返回,比如服务器是JSP,我们会这样做:

...

String jsoncallback=request.getParameter("jsoncallback");

...

out.print(jsoncallback+"({/"account/":/"XX/",/"passed/":/"true/",/"error/":/"null/"})");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: