您如何正确可靠地加载跨站点的JSON数据?

时间:2013-01-08 19:33:55

标签: javascript jquery json jsonp

我目前正在开发针对Chrome的用户脚本/扩展程序,并尝试从“某个网站”提取一些JSON数据。这是我的方法:

$.get( "http://cloud.hartwig-at.de/~oliver/superuser.json", 
       function( data ) { console.log( data ); } 
);

当然,这会导致以下错误:

  

XMLHttpRequest无法加载http://cloud.hartwig-at.de/~oliver/superuser.json。 Access-Control-Allow-Origin不允许原点http://superuser.com

我在阅读Origin 'url' is not allowed by Access-Control-Allow-Origin(以及其他问题)后能够解决这个问题。那么,这是下一个版本:

$.get( "http://cloud.hartwig-at.de/~oliver/superuser.json", 
       function( data ) { console.log( data ); }, 
       "jsonp" 
);

可悲的是,这会导致另一个错误:

  

Uncaught SyntaxError:意外的令牌:(superuser.json:2)

还有一个警告告诉我“资源被解释为脚本但是使用MIME类型text / plain传输:”这已经让我知道问题可能是什么。 (更多细节通过Chrome says "Resource interpreted as script but transferred with MIME type text/plain.", what gives?

提供

显然,the HTTP server has to send the proper MIME type代表我的文件,application/json

好的,我很快就将the required change添加到我的mime.types,然后又去了。但是,没有骰子!警告消失了,错误没有。我仍然得到Uncaught SyntaxError: Unexpected token :。 (我之前也试图利用mimeType parameter来解决这个问题,结果是一样的。)

但MIME类型看起来很好:
enter image description here

现在我有点想法了。 .json文件的内容在http://www.jslint.com/

上有效

2 个答案:

答案 0 :(得分:2)

告诉jQuery做JSONP并没有神奇地使它工作。它生成JSONP request,但另一端的服务器需要支持JSONP调用。

服务器的响应应该类似于

someFunction( { "foo" : "bar" } );

使用JSONP查看jQuery's docs on getJSON以了解如何使用回调

如果它是现代浏览器,您可以使用CORS,并且您可以控制第二个域。

其他选项是您域上的服务器端代理,它请求来自其他域的数据。或者您可以使用Yahoo pipes之类的服务。

答案 1 :(得分:1)

除非服务器支持,否则您不能在请求中使用JSONP。 JSONP调用的方式是您将callback=something参数与请求一起传递,服务器使用something()封装JSON,以便浏览器通过调用something来加载它。访问脚本。

让它运行的另一种方法是配置该服务器以正确设置CORS标头,如果您拥有该域。

如果您无法访问服务器,请考虑using a JSONP proxy,它为您完成了第一步。我使用YQL来做到这一点(参见链接),这不需要我自己设置任何东西。下面是coffeescript代码:

uri = "http://cloud.hartwig-at.de/~oliver/superuser.json"      

jqxhr = $.getJSON \
  "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" \
    + encodeURIComponent(uri) + "%22&format=json&callback=?"  

jqxhr.success (yql) ->
  unless yql.query.results
    alert("Failed to get stuff")
    return      
  json = $.parseJSON(yql.query.results.body.p)
  # do stuff with json

以javascript的形式使用http://js2coffee.org

uri = "http://cloud.hartwig-at.de/~oliver/superuser.json";

jqxhr = $.getJSON("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22"
        + encodeURIComponent(uri) + "%22&format=json&callback=?");

jqxhr.success(function(yql) {
  var json;
  if (!yql.query.results) {
    alert("Failed to get stuff");
    return;
  }
  json = $.parseJSON(yql.query.results.body.p);
  // do stuff with json
});