使用jQuery从子域获取JSON

Ser*_*rov 2 subdomain jquery json jsonp same-origin-policy

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

T.J*_*der 10

$.ajax通过指定使用和JSON-P dataType: "jsonp".链接文档中的详细信息.您的服务器必须使用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);
  }
});
Run Code Online (Sandbox Code Playgroud)

实时复制

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

exampleCallback({
    "foo": "This is foo",
    "bar": "This is bar"
});
Run Code Online (Sandbox Code Playgroud)

这一切都发生了,因为JSON-P不使用XMLHttpRequest同源策略约束,而是使用动态添加的script标签(很好).在我的例子中,标签看起来像

<script type='text/javascript' src='http://jsbin.com/ubucu4?callback=exampleCallback'></script>
Run Code Online (Sandbox Code Playgroud)

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

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