【问题标题】:A question about cross-domain (subdomain) ajax request一个关于跨域(子域)ajax请求的问题
【发布时间】:2010-10-13 12:43:13
【问题描述】:

假设我从http://www.example.com/index.html 加载了主页。在该页面上有向http://n1.example.com//echo?message=hello 发出ajax 请求的js 代码。收到响应后,主页上的 div 会更新为响应正文。

这适用于所有流行的浏览器吗?

编辑:

显而易见的解决方案是在 www.example.com 和 n1.example.com 前面放置一个代理并设置它,以便每个到达 http://www.example.com/n1 子资源的请求都被代理到 http://n1.example.com/

【问题讨论】:

  • 可能不会。这是两个不同的域名,因此跨域请求被浏览器阻止。

标签: javascript ajax


【解决方案1】:

跨域是完全不同的主题。但是跨子域相对容易。您需要做的就是在父页面和 iframe 页面中将 document.domain 设置为相同。

document.domain = "yourdomain.com"

More info here

注意:这种技术will only let you interact with iframes from parents of your domain。它不会改变 XMLHttpRequest 发送的 Origin。

【讨论】:

  • 太糟糕了,选择了另一个“正确”的答案,但不是。这是问题的正确答案。共享二级域的域(除了一些小例外)始终可以将其域设置为允许共享子域的其他域之间进行更广泛的访问。
  • 不用担心,它仍然被评为最高且很容易找到。 stackoverflow 很棒。
  • 也许我很困惑,但他没有提到任何关于 iframe 的内容。这会影响答案的有效性吗?换句话说,当没有 iframe 并且我们正在谈论将子域用作 RESTful api 时,您可以使用此方法吗? (跨浏览器)
  • 我同意在这种情况下对 iframe 的解释具有误导性。但是将 document.domain 设置为指向基本域(剥离子域)应该适用于跨域 AJAX 请求,IIRC。
【解决方案2】:

所有现代浏览器都支持 CORS,因此我们应该利用这一新增功能。

它适用于简单的握手技术,两个域通过发送/接收的 HTTP 标头相互信任。这是期待已久的,因为同源策略对于避免 XSS 和其他恶意尝试是必要的。

要发起跨域请求,浏览器会发送带有 Origin HTTP 标头的请求。此标头的值是提供该页面的站点。例如,假设http://www.example-social-network.com 上的页面尝试访问 online-personal-calendar.com 中的用户数据。如果用户的浏览器实现了 CORS,则会发送以下请求头:

来源:http://www.example-social-network.com

如果 online-personal-calendar.com 允许该请求,它会在其响应中发送一个 Access-Control-Allow-Origin 标头。标头的值指示允许哪些源站点。例如,对上一个请求的响应将包含以下内容:

访问控制允许来源:http://www.example-social-network.com

如果服务器不允许跨域请求,浏览器会将错误发送到 example-social-network.com 页面,而不是 online-personal-calendar.com 响应。

为了允许访问所有页面,服务器可以发送以下响应头:

访问控制允许来源:*

但是,这可能不适合涉及安全问题的情况。

在下面的 wiki 页面中有很好的解释。 http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

【讨论】:

  • IE 8 和 9 不完全支持 CORS。至少对于我的网站来说,这仍然是很大一部分流量。
  • 我猜它适用于 IE9,可能是我错了,因为我一直在使用 jQuery CORS 插件来添加对 IE8+ 的支持。 gist.github.com/mathieucarbou/1114981
【解决方案3】:

另一种可能对您有效或无效的解决方案是在您的 DOM 中动态插入/删除指向目标域的脚本标签。如果目标返回 json 并支持回调,这将起作用。

处理结果的函数:

<script type="text/javascript">
  function foo(result) {
    alert( result );
  }
</script>

您可以动态插入如下内容,而不是执行 AJAX 请求:

<script type="text/javascript" src="http://n1.example.com/echo?callback=foo"></script>

【讨论】:

  • 这种技术被称为 JSONP。主要的 JavaScript 框架在其 AJAX 库中都具有此功能。
【解决方案4】:

另一种解决方法是将 ajax 请求定向到您域上的 php(例如)页面,并在该页面中向子域发出 cURL 请求。

【讨论】:

    【解决方案5】:

    新想法:如果您想要跨子域(www.domain.com 和 sub.domain.com)并且您正在使用 apache。事情会变得容易得多。如果子域实际上是 public_html 中的子目录(sub.domain.com = www.domain.com/sub/。所以如果你有 ajax.domain.com/?request=subject...你可以这样做:www .domain.com/ajax/?request=subject

    对我来说就像一个魅力,没有愚蠢的黑客、代理或困难的事情来做一些 Ajax 请求!

    【讨论】:

      【解决方案6】:

      我找到的最简单的解决方案是在您的子域上创建一个 php,并使用完整路径在其中包含您的原始函数文件。

      例子:

      www.domain.com/ajax/this_is_where_the_php_is_called.php

      子域:

      sub.domain.com

      创建: sub.domain.com/I_need_the_function.php

      在 I_need_the_function.php 中只使用一个包含:

      include_once("/server/path/public_html/ajax/this_is_where_the_php_is_call.php");

      现在从您的 javascript 调用 sub.domain.com/I_need_the_function.php。

      var sub="";
      switch(window.location.hostname)
      {
      case "www.domain.com":
      sub = "/ajax/this_is_where_the_php_is_called.php";
      break;
      case "domain.com":
      sub = "";
      break;
      default: ///your subdomain (or add more "case" 's)
      sub = "/I_need_the_function.php";
      }
      
      
      xmlHttp.open("GET",sub,true);
      

      这个例子很简单。您可能希望使用格式更好的路径。

      我希望这对某人有所帮助。这里没有什么乱七八糟的东西 - 你正在调用原始文件,所以任何编辑都将应用于所有函数。

      【讨论】:

        【解决方案7】:

        我为跨子域编写了一个解决方案,它一直适用于我的应用程序。我在两边都使用了 iframe 并设置了 document.domain="domain.com" 。您可以在以下位置找到我的解决方案:

        https://github.com/emphaticsunshine/Cross-sub-domain-solution

        【讨论】:

          猜你喜欢
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 2013-11-09
          • 1970-01-01
          • 2013-03-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多