3

I have found many similar issues to my problem. Maybe it is me me, but I am having a hard time finding a real clear answer as to why I can't do multiple json requests or why this wouldn't work.

Here is my jQuery code:

$.getJSON('http://api.espn.com/v1/sports/basketball/nba/teams/16/news?apikey=0001234', function(data) {
    console.log(data.headlines);              
});

$.getJSON('http://api.espn.com/v1/sports/football/nfl/teams/16/news?apikey=0001234', function(data) {
    console.log(data.headlines);
});

And here is the error I receive in the console log.

XMLHttpRequest cannot load http://api.espn.com/v1/sports/football/nfl/teams/16/news?apikey=62t2h4tsdmhr2q7aynvjuv2s. Origin null is not allowed by Access-Control-Allow-Origin.

When I run one $.getJSON request by itself it works fine. So I am assuming it is because I am making multiple requests. I am just not sure how to write it in a way where they don't conflict with each other.Any help is appreciated. Thanks

EDIT

So I guess the question then.. Is it possible to do multiple request this way. Is there an issue with my code? Or is it most likely an issue with ESPN's API. I could try using yahoo api and see if I get the same result.

khollenbeck
  • 16,028
  • 18
  • 66
  • 101
  • I'm getting the same response, also when I run the requests separately. – Pieter Jongsma Jul 15 '12 at 18:12
  • Could you post the response received when you make only one request? Chances are you getting the same error but for some reason you are not noticing it... You can see the response received in Firebug or any other browsers developer tools. – Amith George Jul 15 '12 at 18:14
  • @Amith George ... When I do one request I get multiple objects returned from my console.log – khollenbeck Jul 15 '12 at 18:17
  • Works fine for me with both requests from jsfiddle: http://jsfiddle.net/pGBmT/ – Ray Toal Jul 15 '12 at 18:18
  • Are you hitting any rate limits? A random google search suggests that ESPN only allows one call per second: https://github.com/madcaplaughs/PHP-SDK-for-ESPN-API/issues/1 – Amith George Jul 15 '12 at 18:21
  • @RayToal, your fiddle throws a 403 exception for the second request, a sign of hitting the rate limit maybe? – Amith George Jul 15 '12 at 18:22
  • @Amith George ... I have wondered that myself. But I am not really sure how I could tell. In firefox I get a 403 forbidden error. – khollenbeck Jul 15 '12 at 18:22
  • As for whether you can fire two requests at once, RayToal's fiddle proves you cant. When you were getting one response back, were you running that code from a browser js console? Or was it in a file, that you accessed from the browser? If the url began with `file://` then CORS isnt supported and you will get the error you mentioned in your question. – Amith George Jul 15 '12 at 18:31
  • @AmithGeorge .. This is my url file:///Users/krishollenbeck/XCODE_PROJECTS/mn-sports-demo/www/index.html – khollenbeck Jul 15 '12 at 18:32
  • Why not bypass all this and simply use `jsonp`? Assuming espn api supports that... Try appending `&callback=?` to you url... – Amith George Jul 15 '12 at 18:33
  • Yep. Thats the issue. If you read the answer link I posted a few comments above, using a url that begins with `file://` wont support CORS. Try using `jsonp` as suggested above or host the file on some domain. Even `localhost` will do I think. – Amith George Jul 15 '12 at 18:35
  • @Amith George ... Sorry if this is a noobish question. What do you mean by "simply use jsonp"? Isn't that what $.getJson does? Also I tried the &callback=? and the page failed to load. – khollenbeck Jul 15 '12 at 18:37
  • @AmithGeorge I will try to run it on localhost and see what happens.. Just a moment – khollenbeck Jul 15 '12 at 18:38
  • @Amith George ... I tried localhost and got this error... XMLHttpRequest cannot load http://api.espn.com/v1/sports/football/nfl/teams/16/news?apikey=62t2h4tsdmhr2q7aynvjuv2s. Origin http://localhost:8888 is not allowed by Access-Control-Allow-Origin. – khollenbeck Jul 15 '12 at 18:41
  • @Amith George... Nevermind. I got it to work.. I first tried. http://localhost:8888/mn-sports-demo/www/ and then I tried http://localhost:8888/mn-sports-demo/www/index.html and it worked! – khollenbeck Jul 15 '12 at 18:42
  • Thanks everybody for your help. I learned some new things, everybody was very helpful. Hopefully someday I can pay it forward. – khollenbeck Jul 15 '12 at 18:45

3 Answers3

4

Can you fire two json requests one after the other?

Yes. They will not interfere with one another.

Will ESPN return data for both the requests?

Presently No. Your second request will be returned a 403 response. They might change that sometime, who knows...

Why am I getting the error Origin null is not allowed by Access-Control-Allow-Origin.?

As you mentioned in the comments, your script was executing from a url that began with file://. As mentioned in this answer

There are two ways for CORS headers to signal that a cross-domain XHR is OK. One is to send Access-Control-Allow-Origin: * (which, if you were reaching Flickr via $.get, they must have been doing) while the other was to echo back the contents of the Origin header. However, file:// URLs produce a null Origin which can't be authorized via echo-back.

Once you host the file on some server, even localhost, you shoudnt receive that error. As an alternative, you could try using a jsonp request, if ESPN supports it.

Try this query,

$.getJSON('http://api.espn.com/v1/sports/football/nfl/teams/16/news?apikey=0001234&callback=?',     
function(data) {
    console.log(data.headlines);
});

Notice the &callback=? at the end of the url...

Community
  • 1
  • 1
Amith George
  • 5,806
  • 2
  • 35
  • 53
  • Thanks for helping troubleshoot my problem and helping find a resolution. – khollenbeck Jul 15 '12 at 18:47
  • It also looks like I might have an issue with requests from ESPN. Sometimes I have to refresh the page twice before getting all results. None the less the problem was solved. Thanks – khollenbeck Jul 15 '12 at 18:50
  • +1 for quoting the other answer, but (1) _sometimes_ ESPN will serve two subsequent requests; (2) ESPN _sometimes_ gives the error _even when hosted on another server, e.g. jsfiddle, and (3) For JSONP you need to give a real callback (no big deal). Having to refresh the page twice is probably a symptom of rate limiting. – Ray Toal Jul 15 '12 at 19:47
2

There's nothing conceptually wrong with issuing multiple $.getJSON calls. Although, as Amith George mentions in the comments to the original question, you may get 403 responses if you exceed your allowed rate limit. (Twitter uses this response code; I am not sure if ESPN does.)

For me, when these JSON calls are part of an HTML file hosted at a domain, such as jsfiddle.net, I get two objects logged to the console (see http://jsfiddle.net/pGBmT/). This uses jquery 1.7.2.

If I try an old version of jquery (1.3) in an HTML file, I get the error you note.

However when I use jquery 1.7.2 it works fine locally as well (although others have reported occasional problems). This is the file I tried locally:

<!doctype html>
<html>
  <head><meta charset="utf-8"><title>Test</title></head>
  <body>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>
      $.getJSON('http://api.espn.com/v1/sports/basketball/nba/teams/16/news?apikey=62t2h4tsdmhr2q7aynvjuv2s', function(data) {
        console.log(data.headlines);              
      });
      $.getJSON('http://api.espn.com/v1/sports/football/nfl/teams/16/news?apikey=62t2h4tsdmhr2q7aynvjuv2s', function(data) {
        console.log(data.headlines);
      });
    </script>
  </body>
</html>

You can try hitting reload several times in succession. Most of the time I see no problem, but occasionally I get 403s. Often I get one successful response with the origin error on the second.

My best guess is a rate limiting problem. Try placing one of the calls in a setTimeout with a 3 or 4 second delay. When I tried this:

<!doctype html>
<html>
  <head><meta charset="utf-8"><title>Test</title></head>
  <body>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script>
      $.getJSON('http://api.espn.com/v1/sports/basketball/nba/teams/16/news?apikey=62t2h4tsdmhr2q7aynvjuv2s', function(data) {
        console.log(data.headlines);              
      });
      setTimeout(function () {$.getJSON('http://api.espn.com/v1/sports/football/nfl/teams/16/news?apikey=62t2h4tsdmhr2q7aynvjuv2s', function(data) {
        console.log(data.headlines);
      })}, 4000);
    </script>

It worked 5 times in a row with no problems!

Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • Thanks, I've updated my answer. I am 99% sure the problem is with rate limiting and I have a tentative solution for you. I am not sure, though, why the error message you get appears to come from the _browser_ and we get no response when the second request fails. Hopefully someone will come along with a better answer. :) – Ray Toal Jul 15 '12 at 18:56
  • ..That was defiantly part of the problem. I will try the timeout solution to see what kind of user experience I can get. One request per second kind of sucks... so if there isn't anything I can do about that, then I might start looking into alternative API's. – khollenbeck Jul 15 '12 at 19:56
1

I'm having a hard time seeing how even a single getJSON() request could work. You are, by default, not allowed to do cross-domain browser request - which is what your error message states.

To do cross-domain request, you will either have to use JSON-P, if the API support it, or setup a server-side proxy within your own domain, which you can call with your Ajax-request - thus avoiding the cross-domain request.

Christofer Eliasson
  • 32,939
  • 7
  • 74
  • 103
  • There's no problem with cross-domain request using CORS. The weird part is that the origin in the response is null, which usually indicates the local file system. – Ray Toal Jul 15 '12 at 18:14
  • @RayToal Not familiar with EPSN's API, so I don't know if they support CORS. But as you say, the null origin indicates that the file is run locally. – Christofer Eliasson Jul 15 '12 at 18:18
  • 1
    @KrisHollenbeck When you run your files locally, instead of loading the from a web server (a local web server will be enough), the page get a null value for its origin. Because of that, all Ajax-request will fail because the browser cannot make sure that the request is made within the same domain. – Christofer Eliasson Jul 15 '12 at 18:31
  • The Ajax requests do succeed. You can see that ESPN is sending back the `Accept-Origin` response header. Only an ancient browser that does not understand this header will fail the request due to the SOP. The whole reason for CORS is to get around the SOP without resorting to JSONP and [all modern browsers support it](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing#Browser_support). – Ray Toal Jul 15 '12 at 18:54