使用jQuery从子域获取JSON

时间:2011-02-24 14:47:12

标签: jquery json subdomain jsonp same-origin-policy

我有user1.mydomain.comuser2.mydomain.com个域名。我使用api.mydomain.com通过AJAX / JSON处理我的Web应用程序。所以,我想使用jquery这样的user1.mydomain.comapi.mydomain.com/projects发出POST请求:{'action':'getActiveProjects'}以获取JSON中user1的活动项目列表。我找到了$.getJSON方法,但似乎没有选择将一些数据发送到服务器,只有GET方法。我面临的另一个问题是同一起源政策。那么,如何将一些JSON发布到另一个子域上的服务器并获得JSON响应?

3 个答案:

答案 0 :(得分:10)

通过指定dataType: "jsonp"来使用$.ajax和JSON-P。链接文档中的详细信息。您的服务器必须使用JSON-P而不仅仅是JSON进行响应,但如果您控制服务器,这很容易做到。

或者,如果您只需要支持相当新的浏览器(而不是IE),则可以将服务器设置为支持CORS。但是这只在最近的浏览器中得到支持,虽然IE8支持它,但它并不通过通常的XMLHttpRequest对象透明地支持它,而是需要一个完全不同的传输对象(XDomainRequest),jQuery没有为你自动处理(还)。

这是使用jQuery的JSON-P示例:

$.ajax({
  // The source URL
  url: "http://jsbin.com/ubucu4",

  // Tell jQuery you're doing JSON-P
  dataType: "jsonp",

  // Include some data with the request if you like;
  // this example doesn't actually *use* the data
  data: {some: "data"},

  // You can control the name of the callback, but
  // usually you don't want to and jQuery will handle
  // it for you. I have to here because I'm doing this
  // example on JSBin.
  jsonpCallback: "exampleCallback",

  // Success callback
  success: function(data) {
    display("Received data, typeof data = " + typeof data);
    display("data.foo = " + data.foo);
    display("data.bar = " + data.bar);
  },

  // Error callback      
  error: function(jxhr, status, err) {
    display("Error, status = " + status + ", err = " + err);
  }
});

Live copy

在服务器上,您会看到jQuery已在网址中添加了callback参数,例如在上面它将是http://jsbin.com/ubucu4?callback=exampleCallback,但如果你喜欢jQuery控制它的名称将更具异国情调。您的服务器端代码应该构造一个JavaScript函数调用的响应,调用该函数。我在上面的例子中的回答是:

exampleCallback({
    "foo": "This is foo",
    "bar": "This is bar"
});

这一切都发生了,因为JSON-P不使用受Same Origin Policy约束的XMLHttpRequest,而是使用动态添加的script标记(很好)。在我的示例中,标记看起来像

<script type='text/javascript' src='http://jsbin.com/ubucu4?callback=exampleCallback'></script>

浏览器将检索脚本,这是您的JSON-P响应,并执行它。这意味着将调用回调,并将数据提供给您的脚本。

从技术上讲,你的JSON-P响应不是JSON;这是JavaScript,因此您必须将JSON-P与您信任的服务器(例如您自己的子域服务器)一起使用,因为您将代码直接注入页面。否则,如果您使用的某些服务器无法信任,则注入的代码可能会从页面读取信息并将其发送给某些第三方。请注意你的口号。

答案 1 :(得分:1)

您不能使用Ajax / JSON,因为子域是单个域。您可以,但请使用JSONP。 jQuery内置了这个,所以你只需要在你的请求中指定它。看看相关的docs。您不能将POST与JSONP一起使用(这受到此技术工作方式的限制),但没有其他方法可以执行跨浏览器的跨域请求。

答案 2 :(得分:1)

document.domain设置为主域

document.domain = "mydomain.com"

More info here