Using JSONP for cross-host "Ajax" calls with jQuery

When trying to make cross-host Ajax calls, you’ll likely run foul of the browser’s “same origin policy”. Usually, the user will be presented with a pop-up similar to this:

This page is accessing information that is not under its control.

One solution is JSONP. It happens that the same origin policy is relaxed for certain tags and that includes the <script> tag. JSONP takes advantage of this by writing a <script> tag to the document (instead of using the XMLHttpRequest object of traditional Ajax). The src attribute of the script tag specifies the Ajax URL. Instead of the traditional HTML response, the server returns JavaScript; more specifically, a JSON object wrapped in a function call. In many implementations, the JSON simply encapsulates a HTML fragment and the called function loads it somewhere in the document.

Obviously, due to the nature of JSONP, POST requests are not available.

jQuery makes implementing the client-side of JSONP straightforward through the ajax() method. Here’s an example (assume “host1” is hosting the page and “host2” is serving Ajax requests):

$.ajax({
  url: ‘http://host2/GetJSON’,
  dataType: ‘jsonp’,
  success: function(data) {
    $(‘#content’).html(data.html);
  }
});

jQuery will append a call-back method name to the query-string of the URL: http://host2/GetJSON?callback=jsonp1265718231899

It is the responsibility of the server-side code to output JavaScript that calls the method supplied in the query-string. So, given the above request, host2 would return JavaScript that looks like this:

jsonp1265718231899({ html: "<h1>HTML Fragment</h1>" });

The JSON object ({ html: "<h1>HTML Fragment</h1>" }) is passed to the success call-back. In this particular example the success call-back simply updates the document with the value of the html property.

jQuery is a powerful JavaScript library with all kinds of useful functionality in addition to Ajax support. If you haven’t tried it already, I recommend you do. You won’t look back.

Comments are closed.