0

I'm currently working on a userscript/extension for Chrome and am trying to pull in some JSON data from "some website". This was my approach:

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

Of course, that leads to the following error:

XMLHttpRequest cannot load http://cloud.hartwig-at.de/~oliver/superuser.json. Origin http://superuser.com is not allowed by Access-Control-Allow-Origin.

I was able to resolve that after reading Origin 'url' is not allowed by Access-Control-Allow-Origin (among other questions). So, this is the next version:

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

Sadly, that results in another error:

Uncaught SyntaxError: Unexpected token : (superuser.json:2)

There's also a warning telling me "Resource interpreted as Script but transferred with MIME type text/plain:" which already gave me an idea what the trouble could be. (And more details were provided through Chrome says "Resource interpreted as script but transferred with MIME type text/plain.", what gives?)

Apparently, the HTTP server has to send the proper MIME type for my file, which would be application/json.

Okay, So I quickly added the required change to my mime.types and went for another go. But, no dice! The warning went away, the error didn't. I still get Uncaught SyntaxError: Unexpected token :. (I had also previously attempted to utilize the mimeType parameter to fix this, the outcome was the same.)

The MIME type looks fine though:
enter image description here

Now I'm somewhat out of ideas. The content of the .json file validates fine on http://www.jslint.com/

Community
  • 1
  • 1
Der Hochstapler
  • 19,560
  • 15
  • 87
  • 126
  • Target a server-side script (asp,php,etc) that returns proper jsonp, or use a static callback and tell jQuery to use it. If you don't know what i'm talking about, do some research on what jsonp is. jsonp involves json, but they are not one and the same. – Kevin B Jan 08 '13 at 19:35

2 Answers2

2

Telling the jQuery's get to do JSONP does not magically make it work. It makes a JSONP request, but the server on the other end needs to support JSONP calls.

The response from the server should look something like

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

See jQuery's docs on getJSON with JSONP to see how to use the callback

If it is a modern day browser you can use CORS and you have control over the second domain.

Other option is a serverside proxy on your domain that requests data from the other domain. Or you can use a service like Yahoo pipes.

epascarello
  • 185,306
  • 18
  • 175
  • 214
1

You can't use JSONP on a request unless the server supports it. The way JSONP calls work is that you pass a callback=something parameter along with the request and the server encapsulates the JSON with something() so that it can be loaded by your browser by calling something when the script is accessed.

Another way to get it to work is to configure that server to set the CORS headers correctly, if you own the domain.

If you don't have access to the server, consider using a JSONP proxy, which wraps the first step for you. I've used YQL to do this (see the link), which doesn't require me to set anything up myself. Below is coffeescript code that does that:

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

And in the form of javascript using 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
});
Community
  • 1
  • 1
Andrew Mao
  • 31,800
  • 17
  • 126
  • 212
  • Using the YQL approach as outlined in http://stackoverflow.com/questions/8537601/is-there-a-free-json-proxy-server-which-supports-cors-or-jsonp allowed me to resolve this quickly. Thanks. – Der Hochstapler Jan 08 '13 at 19:59
  • I posted my own code because if I remember correctly, using the code verbatim on that question didn't work for me. – Andrew Mao Jan 08 '13 at 20:01
  • For future reference, when using YQL it can be desirable to also pass [jsonCompat=new](http://developer.yahoo.com/yql/guide/json_to_json.html) to avoid lossy data conversion. In my case, omitting the parameter caused the keys in the JSON object to be changed when they contained certain characters. – Der Hochstapler Jan 08 '13 at 20:56