July 16, 2009
This is part II of How to create dynamic javascript widget( Link is not available).
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 to get event data you will get following error.
Access to restricted URL 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 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.
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
jQuery makes it easy to use JSONP. Look for documentation on how to use JSONP with jquery here .
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.
In this case callback is being passed but the name is jsoncallback.
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 (Link is not available) 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
.
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.
If this blog was helpful, check out our full blog archive.