在另一个域/服务器上请求内容

时间:2011-11-30 06:54:29

标签: javascript ajax

我正在尝试请求位于另一个域/服务器上的数据,但是当我尝试发送请求时,我收到了异常。

var request = new XMLHttpRequest();
request.open("GET", "http://www.w3schools.com/ajax/cd_catalog.xml", false);
request.send();

错误:

未捕获的异常:[例外...“组件返回失败代码:0x80004005(NS_ERROR_FAILURE)”nsresult:“0x80004005(NS_ERROR_FAILURE)”]

这是请求不在同一域/服务器上的内容的正确方法吗?或者还有其他方法可以实现这一目标吗?

我在firefox 8.0中对此进行测试,但我想要一个适用于所有主流现代浏览器的解决方案。

4 个答案:

答案 0 :(得分:3)

出于安全原因,这样的请求不起作用。想象一下,如果任何域名可以访问任何其他域名的数据 - 您最终会得到任何网站(例如www.sketchyattacksite.com)能够从任何其他网站(例如www.bankofamerica.com)提取任意内容,包括经过身份验证的用户保密会议信息。所有现代浏览器都实现了same origin policy,以防止发生此类安全违规行为。

有几种常见的方法来绕过相同的原始政策:

  1. 您从中请求数据的域可以将所述数据作为JSONP返回(这使您可以加载它,就好像它是外部脚本一样,不受同一原始策略的约束)。站点通常会在其API中提供JSONP格式,例如:https://graph.facebook.com/cocacola?callback=name_of_function_to_pass_data_via_jsonp
  2. Cross-Origin Resource Sharing (CORS)是最近的标准,因此仅适用于较新的浏览器,但允许网站指定(通过HTTP标头)他们将允许访问其数据的域。例如,如果由于某种原因美国银行想要允许www.sketchyattacksite.com向www.bankofamerica.com提出请求,他们可以返回Access-Control-Allow-Origin: sketchyattacksite.com标题。
  3. 服务器端代理。您可以在服务器上创建一个处理程序,其唯一功能是检索目标http://www.w3schools.com/ajax/cd_catalog.xml文件并将其返回到您的域中。请注意,这解决了可能传递机密数据的问题,因为您的服务器(在w3schools.com上无法访问用户的cookie)代替用户的浏览器发出请求。
  4. 在这种特殊情况下,它看起来像#3,一个服务器端代理,是答案。为什么?因为您无法控制您从中请求数据的网站(意味着您无法利用#1或#2,除非w3schools.com自己选择实施这些数据)。

    这是一个simple PHP example of a serverside proxy,由雅虎提供!关键是它被锁定为只从特定域中提取内容(这样不好的参与者就不能将它用于看似代表你的任意请求),除此之外,它就像通过请求目标URL一样简单卷曲并将其返回给用户。请注意,您可能还希望添加缓存以防止服务器端代理的每次加载触发http://www.w3schools.com/ajax/cd_catalog.xml文件的新请求。

答案 1 :(得分:2)

您无法直接从其他域检索内容。您可以通过为您完成工作的服务器(代理)或使用JSONP之类的东西来检索内容。请检查此wikipedia page

有关该主题的更多信息,this page可能很有趣

答案 2 :(得分:2)

这称为跨域Ajax,大多数浏览器认为这是安全违规。一种解决方法是创建服务器端组件(与您正在查看的页面相同的域),该组件将从其他服务器(在您的情况下为/www.w3schools.com)请求数据并将其回送给您的Ajax请求。

这些链接将解释问题和几个解决方案:

http://jimbojw.com/wiki/index.php?title=Introduction_to_Cross-Domain_Ajaxrequest

http://usejquery.com/posts/the-jquery-cross-domain-ajax-guide

答案 3 :(得分:1)

是一个跨域请求,它始终使用服务器上的代理执行。您创建服务器请求并在该页面上调用http://www.w3schools.com/ajax/cd_catalog.xml,如abc.apsx,并使用javascript调用您自己的abc.aspx

var request = new XMLHttpRequest();
request.open("GET", "abc.aspx");
request.send();