【问题标题】:XMLHttpRequest Same Origin PolicyXMLHttpRequest 同源策略
【发布时间】:2013-11-09 12:10:03
【问题描述】:

我花了 3 天时间研究如何使用 XMLHttpRequest 进行跨域请求。最好的选择确实是我已经在使用的 JSONP。

但我仍然有一个问题,我无法在任何地方找到答案。我阅读了数百篇帖子(包括 SO),但没有人有一个很好的可靠答案(有很好的参考)。希望这里有人可以提供帮助。

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

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

当我检查 Firebug Net 选项卡时,我意识到请求没有被阻止!这是明确要求的。我简直不敢相信。所以我在 domain.com/log.php 中创建了一个文件,我可以在其中记录任何访问我的域的请求。令人惊讶的是,我触发 localhost 的所有请求都在访问我的 domain.com。当我尝试获取响应时,由于我的 Chrome 和 FIrebug 浏览器的源策略相同,我真的无法得到它。但是,尽管我无法操纵响应者,但请求确实到达了网络服务器,这让我感到非常惊讶。

更令人惊讶的是,如果 domain.com/log.php 生成了 1MB 的巨大响应,我的萤火虫向我显示浏览器确实从网络服务器下载了全部 1MB,最后它显示一条消息“访问被拒绝”正如预期的那样。那么,如果同源策略禁止读取该数据,为什么还要下载所有文件。

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

让我感到不安的是,它可能会打开一个巨大的安全漏洞,一个每天有数千次浏览量的网站可能会运行这 3 行代码,并在一个不友好的网站上引发巨大的 Ddos 攻击,只是让用户请求一个页面由于浏览器不会阻止请求,因此每隔一小段时间在另一个网站上。

我在 IE 7、8 和 9 以及 Chrome 最新版本和 Firefox 最新版本中测试了此脚本,其行为是相同的:请求已完成,浏览器下载所有响应,但无法执行 SOP。

希望有人能解释一下为什么规格如此错误或我的理解错了!

【问题讨论】:

  • 好问题。不知道为什么请求会到达外部域。我在这里做了一个测试,和你一样,请求已经完成,但是我无法获取响应。希望有人帮忙。
  • 您能否检查domain.com 是否启用了CORS.... 但如果是这样,IE 应该无法工作...您可以通过什么方式确认
  • @ArunPJohny 不,CORS 未启用。这是一个示例网站。您可以将 domain.com 更改为任何域,您将在 Firebug 或 Chrome Net Console 中看到请求已完成且没有错误。很明显,这不是一个错误,因为我测试的所有浏览器的行为方式都相同,但是为什么规范说跨域 ajax 请求的请求“被阻止”。
  • 我只是想让你知道,我在过去的几个小时里做了几个测试,在所有情况下请求都成功并到达了服务器!这真的很奇怪!感谢您发布这个问题。

标签: javascript ajax xmlhttprequest


【解决方案1】:

发生这种情况是因为通过评估从服务器返回的以下访问控制标头值,在客户端(浏览器)应用了相同的源策略:

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

如您所见,请求必须首先在服务器上完成,以便浏览器检查返回的标头。这正是您的请求在服务器上执行的原因。

你可以看看Priciples of the Same-Origin Policy by A. Barth

【讨论】:

  • 根据问题“浏览器确实下载了所有 1MB”。所以我想知道浏览器是否真的需要下载所有这些,因为响应应该以标头开头,告诉它不要下载这个。
【解决方案2】:

请参阅bobince's answer 的类似问题:

根据 XMLHttpRequest 级别 2,浏览器允许跨域 GET 未经预检发送,但不允许从中读取结果 响应,除非远程域选择加入。没有额外的 此处存在漏洞,因为您已经可以将 GET 导致任意 要发送的 URL(包括查询字符串,对于它的价值)通过 多个更基本的接口。

例如,您总是能够创建一个元素 它的 src 设置为远程域上的地址;拿走那个 跨域能力会破坏很多现有的网络。

相关:

【讨论】:

  • > 这里没有额外的漏洞......我想知道。我了解跨域 GET 需要使用 IMG 和 IFRAME 和 SCRIPT -tags。但是它是否需要在意味着 XmlHttpRequest 的 WITHIN 脚本中工作?如果不是这样,它对黑客来说似乎更有力量。我想知道是否更好的方法是让浏览器使用 HEAD 来获取凭据。
猜你喜欢
  • 2010-12-22
  • 2013-07-20
  • 1970-01-01
  • 2015-02-12
  • 2011-01-17
  • 2012-10-30
  • 2011-12-26
  • 2019-04-28
相关资源
最近更新 更多