This is part II of How to create dynamic javascript widget.

What problem JSONP solves?

Browsers do not allow cross-domain Ajax requests. For example if you try to make Ajax request to http://www.eventsinindia.com/events/14633.js [update: link not working] to get event data you will get following error.

Access to restricted URI denied.

In order to get around this security problem you can do any number of things including sending the Ajax request to your server which will get the JSON data from the eventsinindia.com API. Or use iframe. Both of these solutions are implemented and discussed in this article .

However in some cases JSONP solves this problem much more elegantly.

Before we discuss JSONP some basics ?

Before looking at JSONP let’s cover some basics. When a html page includes a javascript file then the html code looks something like this.

<script src="http://neeraj.name/javascripts/color.js" type="text/javascript"></script>

There are two things to notice here. First is that the source of the javascript file could be cross-domain. It means your html page can point the source of your javascript file to http://neeraj.name/javascripts/cache/all.js and all.js will be loaded by the browser. This feature which allows cross-domain loading of javascript file is the basis of JSONP.

The second thing to notice is that the javascript written in color.js is immediately evaluated after the source file has been loaded. For example the content of color.js could be this.

alert('hello');

When the html page is loaded you will get an alert.

Let’s recap: In the above section I showed you how you can point the source of your javascript file to a domain that is not yours (cross-domain) and the code loaded from the domain is immediately evaluated.

What is JSONP?

From the above section it is clear that if by some means we could dynamically create a script node and point the source of that node to cross-domain and if the remote site returns a javascript function then that function will be evaluated.

However in the world of JSON we only get JSON data from the remote server. If we want to stick the returned JSON data on our page then that data needs be used by a javascript function. And that’s where JSONP comes in handy.

Let’s take an example. If you make a call to http://www.eventsinindia.com/events/14633.js you will get JSON data back.

{"name": "Craft Classes" , "start_date": "2009-05-01" , ....}

However what you really want is to do is to stick this data on your html page by invoking a javascript function like this

AddThisDataToPage({"name": "Craft Classes" , "start_date": "2009-05-01" , ....});

What needs to be done is while making a call to http://www.eventsinindia.com/events/14633.js pass a parameter called callback . So in this case the full url would look something like this

http://www.eventsinindia.com/events/14633.js?callback=AddThisDataToPage

Remember callback is a special word here. By using callback we are telling API to wrap the response JSON data with a call to function named AddThisDataToPage.

Click on following two links to see the difference. The first link is returning pure JSON data while the second link will return a javascript function.

http://www.eventsinindia.com/events/14633.js

http://www.eventsinindia.com/events/14633.js?callback=AddThisDataToPage

Using JSONP with jQuery

jQuery makes it easy to use JSONP. Look for documentation on how to use JSONP with jquery here .

Callback is not the name everyone uses

Most of the people use callback as the key word to identify client is asking for JSONP data. However some people use a different keyword. For example flickr uses the keyword jsoncallback

This returns JSON data

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json

In this case callback is being passed but flickr ignores it.

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&callback=show

In this case callback is being passed but the name is jsoncallback.

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=show

Providing support for JSONP

All the APIs should provide support for JSONP. Enabling JSONP support is easy if you are using Rails 2.3 or any Rack compliant framework. In Rails 2.3 all you need to do is stick this file in lib as jsonp.rb and then add one line to the environment.rb .

#environment.rb

Rails::Initializer.run do |config|
  .....
  config.middleware.use 'Jsonp'
end

That’s it. Now you are providing support of JSONP with the keyword being callback.

Security

Since the data from external source is read and then that data is evaluated on run time by Javascript, there is potential for security breach. So be careful when you are using JSONP. Only load data from a trusted source.