2013-10-30 276 views
11

我花了最近3天学习如何使用XMLHttpRequest进行跨域请求。最好的选择是我已经使用的JSONP。XMLHttpRequest同源策略

但我仍然有一个问题,我无法找到答案无处。我读了数百篇文章(包括SO),没有人有很好的答案(很好的参考)。希望这里的某个人能够帮忙

表示,我在很多网站上读到,由于安全原因,我无法向域aaa.com发送Ajax请求到bbb.com并获取我想要的数据。这很清楚,我对此毫无疑问。但问题是当我运行下面的代码在我的本地主机(所以我的域名是“localhost”,我不应该能够从另一个域请求任何数据)。

xhReq = new XMLHttpRequest(); 
xhReq.open("GET","http://domain.com?parameter",true); 
xhReq.send(null); 

当我检查Firebug Net Tab时,我意识到请求没有被阻止!它被明确要求。我无法相信。所以我在domain.com/log.php中创建了一个文件,我可以记录任何打到我的域名的请求。令人惊讶的是,我发布localhost的所有请求都击中了我的domain.com。当我试图获取响应时,我真的无法得到它,因为我的Chrome和FIrebug浏览器采用了相同的源策略。但我真的很惊讶,尽管我无法操纵responde,但请求确实触及了Web服务器。

更令人惊讶的是,如果domain.com/log.php产生一个像1MB一样的巨大responde,我的萤火虫显示我浏览器确实从网络服务器下载了所有的1MB,最后它显示一条消息“Access denied “如预期。那么,为什么要下载所有的文件,如果相同的来源策略禁止读取数据。

最后,我让我感到惊讶的是,我读的所有网站和规范都说非常明确,当目标域与源域不匹配时,使用Ajax阻止请求。但显然,在我的实验中,尽管我无法访问响应数据,但请求正在完成。

让我不高兴的是它可能会打开一个大的安全漏洞,每天有数千个视图的网站可以运行这3行代码,并在不友好的网站中导致巨大的Ddos攻击,只是让用户请求因为浏览器不会阻止请求,所以会在很短的时间间隔内访问另一个网站。

我在IE 7,8和9中测试了这个脚本,并且Chrome的最新版本和Firefox的最新版本和行为是一样的:请求完成并且浏览器下载了所有的响应,而不是使它成为可执行的SOP。

希望有人可以解释为什么规范是如此错误或我是错误的理解!

+0

有趣的问题。不知道为什么请求到达外部域。我在这里做了一个测试,并且和你一样,请求已完成,但我无法获取响应。希望有人帮助。 – amandanovaes

+0

你可以检查'domain.com'是否启用了[CORS](http://www.w3.org/TR/cors/)....但如果是这样的话IE不应该工作......你可以通过任何方式确认 –

+0

@ArunPJohny不,CORS未启用。这是一个示例网站。您可以将domain.com更改为任何域,并且您将在Firebug或Chrome网络控制台中看到请求已完成且没有错误。很显然,这不是一个错误,因为我测试的所有浏览器的行为方式都是相同的,但为什么规范说明请求“被阻止”用于跨域ajax请求。 – Samul

回答

1

这是因为通过评估下列访问控制报头在客户端(浏览器)应用相同的起源策略值从服务器返回

  • 访问控制允许来源
  • 访问控制允许的方法
  • 访问控制允许报头

正如你所看到的,要求必须先在服务器上完成以便浏览器检查返回的标题。这正是您的请求在服务器上执行的原因。你可以看看Priciples of the Same-Origin Policy by A. Barth

1

bobince's answer在一个类似的问题:

按XMLHttpRequest的2级,浏览器允许跨域获取要 没有预检发送,但不允许结果与 响应读除非远程域选择进入。这里没有额外的 漏洞,因为您已经可以通过 多个基本接口导致发送GET到任意 URL(包括查询字符串,它的价值)。

例如,您始终可以使用 创建一个元素,其src设置为远程域上的地址;带走 跨域能力会打破很多现有的网络。

相关: