【问题标题】:request content on another domain/server在另一个域/服务器上请求内容
【发布时间】:2011-11-30 06:54:29
【问题描述】:

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

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 中对此进行测试,但我想要一个适用于所有主要现代浏览器的解决方案。

【问题讨论】:

    标签: javascript ajax


    【解决方案1】:

    出于安全原因,这样的请求将不起作用。想象一下,如果任何域都可以访问任何其他域的数据 - 您最终会得到任何站点(例如 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)发出请求。

    在这种特殊情况下,看起来#3,一个服务器端代理,就是答案。为什么?因为您无法控制请求数据的站点(这意味着您无法利用 #1 或 #2,除非 w3schools.com 自己选择实施它们)。

    这是simple PHP example of a serverside proxy,由 Yahoo! 提供。关键是它被锁定为仅从特定域中提取内容(因此不良行为者无法将其用于看似代表您提出的任意请求),除此之外,它就像通过以下方式请求目标 URL 一样简单curl 并将其返回给用户。请注意,您可能还想添加缓存以防止服务器端代理的每次负载触发对 http://www.w3schools.com/ajax/cd_catalog.xml 文件的新请求。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        这被称为跨域 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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-07-17
            • 2013-07-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多