posts - 82, comments - 269, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理



AJAX不能跨域访问是什么意思,我想没有亲自遇到这个问题的人,可能根本就不理解.现在我给出一个例子,让大家体会一下什么是跨域访问.这个页面就是一个HTML文件,源码我附文章后面了.

注:这个页面并不高深,例子只有一个HTML页面,没有引用什么特别的库之类的.例子的目的只是让对AJAX不能跨域访问有一个感性的认识.就好比,你如何告诉一个没见过汽车的人,告诉他什么是汽车,讲半天,还不如直接给个汽车给他看看,他就知道什么是汽车了.但你要他直接给一个清晰的定义,或者是让他明白汽车的动力学,这就是很难的了,也不是本文的目的.


下面这个简单的代码只要复制到一个本地html文件中即可,就可以把任何URL指定的网页显示出来[注1],但是同样的页面,你如果放到tomcat之类的容器下面,就无法打开,甚至通过网络邻居访问都不行.

 

分析1:为什么好好的页面却得不到期望的结果:
为什么JS语法没有什么问题,放在网络邻居与web容器中就不能正常运行了呢,这就是AJAX所说的不能跨域访问,因为浏览器你这个JS程序是来自容器,它就限制你只能正常访问同一容器里的的资源[注:2],比如你通过http://www.openj.cn访问到一个页面,那么这个页面的JS就只能访问openj.cn的资源,而不能访问www.baidu.com.


为什么IE在通过本地文件能正常运行这个页面的,我是在XP下测试的,可能IE把本地这个域处理成了一个特殊的域,从这个域得到的JS程序,权限可以略微放松些,这样可能易用性就会好些,要知道安全性与使用的方便性可是此消彼长的关系.所以IE选择了易用性,在安全问题上放了一个黄灯,为什么说是黄灯呢,因为它在运行这个页面时,IE会给出一个安全提示,告诉你这个页面存在风险.

分析2:为什么要限制AJAX跨域访问[注3]:
可以肯定的说是出于安全的需要,但我没有找到什么资料明确这个问题分析,我只能通过看其它资料来自己体会了,我自己发现的一个安全问题就是:
AJAX可能会把用户的cookie信息泄漏出去,比如我往别用户的Gmail信箱里面发嵌有JS脚本的邮件.这些脚本读取gmail.com域中的cookies信息,然后通过AJAX发送给我的个人网站,这样我的个人网站就可以得到这个用户的Gmail的cookies.我然后把它提取出来,我就可以不用密码来访问这个用户的Gmail邮箱了.
这个只是我能想到的,我想如果能够让AJAX能够跨域访问的话,肯定还有其它一些安全问题.


[1];对这个测试页面好像只有在一种情况下才能正常执行:就是通过IE打开本地文件。如果用FireFox就算是通过本地文件打开它也不能正常运行。
[2]:为了把问题简单说明,我说了只能访问同一容器里面的资源,实际上是不精确的,真正的还是应该通过域来区分,同一个容器里面的资源也可能是指向不同的域.同一个域的各个资源也可能分布在不同的容器中.比如:tomcat中有好2个虚拟目录,你用不同的域名来指向这两个虚拟目录,这个容器中的两个虚拟目录就是不同的域了.不同容器的资源也可能属于同一个域,比如我申请一个域名:openj.cn,我设置 www.openj.cn指向www.baidu.com,而blog.openj.cn指向www.google.com。这样baidu与google的首页就都属于openj.cn这个域了.
[3]: 本文没有区分AJAX的跨域与JS的跨域,因为AJAX就是通过JS来发现请求的,它们实际上是一回事。
[4]: 在代码中,我定义了变量 var url = 'http://www.google.com';    你可以把它修改为任何你能访问的地址,
[5]:本文的内容全是自己的瞎体会的,如果有什么不对的有高手发现了,希望大家能指出。这也是本文的主要目的。




 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML xmlns="http://www.w3.org/1999/xhtml">
<HEAD><TITLE>AJAX跨域验证</TITLE>

<script>
var xmlHttp;
function createXMLHttpRequest() {
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}

function hello() {
 var url = 'http://www.google.com';   
 createXMLHttpRequest();
 xmlHttp.onreadystatechange = showResponse;
 xmlHttp.open("GET", url, true);
 xmlHttp.send(null);
}

function showResponse(){
  if(xmlHttp.readyState == 4) {
 if(xmlHttp.status == 200) {        
 document.getElementById("result").setAttribute("value",xmlHttp.responseText) ;
 }
 }
}
</script>

</HEAD>

<BODY> 
 <input type="button" value="hello" onclick="hello()"><br/><br/>
 <textarea id="result" name="result" cols=100 rows=100 ></textarea>
</BODY>
</HTML>

 

 

 


 


评论

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2007-02-12 16:51 by TiGERTiAN
其实Ajax跨域访问还是可以解决的,不过需要用到后台服务端。
例如用户访问www.go.com,但go.com需要调用come.com的信息
那么Ajax将需要跨域的数据交给www.go.com/send.asp
然后再由send.asp发送到come.com,come.com反馈信息,go收到信息后,再由交给js写出来,实际开发中用的就是此方法,前提是此信息不能过于频繁交换或者流量过大。不知道其他人还有没有更好的方法。

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2007-02-12 18:38 by emu
总的来说,跨域我认为是浏览器开发者小心过头的产物。一个合理的跨域限制策略应该是像flash那样的,读取一个crossdomain.xml配置文件后就允许或者拒绝访问。
Firefox的跨域访问限制更恶心,一设置domain以后,连不跨域的请求都被禁止了,真是有病。

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2007-02-15 10:01 by bezy
AJAX cross-domain js cross-domain 都可以解决的。。
而且不需要通过后台。。。。google ajax cross domian ..
现在流行两种解决方案。。。

一种是 iframe 的桥接
另一种是iframe 的代理

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2007-02-15 11:13 by itspy
@bezy


楼上的可以弄一个简单的例子吗?比如修改一下上面的示例,如何得到Google首页的返回?

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2007-02-15 20:14 by TiGERTiAN
了解。。。Iframe可以连接到外部的网页而且没有警告,然后通过js来获取所需数据。。。
现在好像Webservice可以解决cross-domain的调用。。就是不太知道如何使用

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2007-06-29 08:24 by newgo
function hello() {
var url = 'http://www.google.com';
createXMLHttpRequest();
xmlHttp.onreadystatechange = showResponse;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}

url用'http://www.google.com';要改一下,不然连本地都显示不了.

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例][未登录]  回复  更多评论   

2008-01-03 16:46 by ben
一种是 iframe 的桥接 和 另一种是iframe 的代理 是什么意思?

Webservice可以解决cross-domain的调用嘛?这么我的不行。。

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2008-06-26 13:43 by pudn
防止跨域访问,是为了防止服务器拥有者或黑客像其他网址提交本站用户私有信息,如帐号和密码

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2008-07-20 19:38 by chester
不懂...url换成别的如baidu就可以了?为什么?

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例][未登录]  回复  更多评论   

2010-10-30 15:25 by k
我也碰到这样的问题 怎么解决呢

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例][未登录]  回复  更多评论   

2010-10-30 15:27 by k
@emu
赞同!

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2012-10-11 17:00 by 涂老
jsonp

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2013-08-21 16:16 by sdf
为什么我的不行呢?

# re: 初步体验“AJAX不能跨域访问”(原创)[有源码,有示例]  回复  更多评论   

2013-10-29 22:56 by 3a教程网

ajax jsonp跨域的方法实例方法
http://3aj.cn/article/4949.html

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问