1

I am trying to connect to the RubyGems API, but when I try to get the JSON I get an stange error.

Uncaught SyntaxError: Unexpected token :

I have seen this error in other questions and posts, but none of the worked for me.

Here is my $.getJSON() function

.getJSON("http://rubygems.org/api/v1/gems/rails.json?jsoncallback=?", function(data) {
  ...function stuff....
});

This is the JSON that I should receive:

{"dependencies":{"runtime":[{"name":"actionmailer","requirements":"= 3.0.9"},{"name":"actionpack","requirements":"= 3.0.9"},{"name":"activerecord","requirements":"= 3.0.9"},{"name":"activeresource","requirements":"= 3.0.9"},{"name":"activesupport","requirements":"= 3.0.9"},{"name":"bundler","requirements":"~> 1.0"},{"name":"railties","requirements":"= 3.0.9"}],"development":[]},"name":"rails","downloads":4474748,"info":"Ruby on Rails is a full-stack web framework optimized for programmer happiness and sustainable productivity. It encourages beautiful code by favoring convention over configuration.","version_downloads":93309,"version":"3.0.9","homepage_uri":"http://www.rubyonrails.org","bug_tracker_uri":"http://rails.lighthouseapp.com/projects/8994-ruby-on-rails","source_code_uri":"http://github.com/rails/rails","gem_uri":"http://rubygems.org/gems/rails-3.0.9.gem","project_uri":"http://rubygems.org/gems/rails","authors":"David Heinemeier Hansson","mailing_list_uri":"http://groups.google.com/group/rubyonrails-talk","documentation_uri":"http://api.rubyonrails.org","wiki_uri":"http://wiki.rubyonrails.org"}

Can someone please help me :)

3
  • Are you sure that's the correct parameter for the callback name? That API might not support JSONP. Commented Jul 6, 2011 at 1:36
  • The problem is that when I remove the parameter I get this XMLHttpRequest cannot load rubygems.org/api/v1/gems/cancan.json?. Origin localhost:3000 is not allowed by Access-Control-Allow-Origin. Commented Jul 6, 2011 at 1:54
  • Yes, you need to use JSONP for cross domain requests (unless they change that header - and that only works in some browsers). But since the callback parameter isn't working for that API you're getting a response that the browser can't interpret correctly. Commented Jul 6, 2011 at 2:03

4 Answers 4

8

What makes you think that rubygems.org supports JSONP at all? I don't see any mention of JSONP in the documentation and when I do this:

lynx -dump -source 'http://rubygems.org/api/v1/gems/rails.json?jsoncallback=x'

I get the same plain old JSON as I do from

lynx -dump -source 'http://rubygems.org/api/v1/gems/rails.json'

The only difference between the two is the downloads and version_downloads change but that's to be expected.

When you use jsoncallback=? in the query string, jQuery will set up a callback function and assume that the remote URL will send back JavaScript (not JSON!) that will call the specified function. So, if the remote service sends back JSON when you're expecting JavaScript, the browser will end up trying to interpret the JSON as JavaScript and get upset because

{"dependencies":{"runtime":[{"name":"action ...

is not a valid JavaScript statement. This sounds exactly like the error you're seeing.

I think you're going to have to proxy the JSON through your own server. You'll need a controller on your server that makes that makes the call to get the JSON and then simply echoes it back to your JavaScript, this will get your around both the lack of JSONP support and your cross domain problem in your client.

Sign up to request clarification or add additional context in comments.

3 Comments

Hey man, really I'm not that good with all this JSON stuff, but I used to have the Access-Control-Allow-Origin error and they told me to add the JSONP options, to get around that error, but now I am stuck with this, problem. Do you know how to pass through the ccess-Control-Allow-Origin error without adding the JSONP?
@rogeliog: I've added some more explanation in an update. I think you're going to have to set up a simple proxy controller to get around the lack of JSONP and the cross domain request problem at the same time.
this all explains the error indeed, check the post below here (made by CD Sanchez) on how to fix this
2

The browser is interpreting the curly brackets as a block. The API needs to return a function call with the JSON data as the argument (using the supplied callback name). It doesn't appear that this API supports JSONP & the callback parameter so you'll need to contact them to ask for this support.

It should return something like:

jsonp1279196981233({ ... })

rather than simply:

{ ... }

because the client will be evaluating it as a script. In JavaScript a set of stand alone curly braces will denote a block.

Comments

0

Given that you're passing in a data-handler function to getJSON(), are you sure you want the JSONP callback parameter? Try removing ?jsoncallback=? from the URL:

.getJSON("http://rubygems.org/api/v1/gems/rails.json", function(data) {
    ...function stuff....
});

4 Comments

The problem is that if I remove the ?jsoncallback=? I get this {XMLHttpRequest cannot load rubygems.org/api/v1/gems/cancan.json?. Origin localhost:3000 is not allowed by Access-Control-Allow-Origin.}
I assume he doesn't own rubygems.org, so he needs to use JSONP since it would be a cross domain request.
I can successfully load the URL without the trailing ? and receive a JSON object that begins with what you said you were expecting. Your error message has a trailing ? in the URL. Is that intentional or a cut-and-paste error? Make sure the URL ends with .json without a question mark.
Why wouldn't he be able to query a URL and get some JSON back? I understand there are cross-domain differences between what I type in my browser's address bar and what goes into a JavaScript file I load, but it seems odd that a JS file couldn't hit a server in a different domain to retrieve some JSON. I've clearly spent too much time on the back-end.
0

Related... If you are not returning valid JSON you will see this error, JSONP aside.

For me I was

format.json { render :json => ActiveSupport::JSON.encode({:foo => true}) :status => :ok }
=>
{
  'foo': true
}

When I should have been

format.json { render :json => ActiveSupport::JSON.encode([{:foo => true}]) :status => :ok }
=>
[
  {
    'foo': true
  }
]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.