Jump to content

Making an Ajax Request to Another Domain (Using JSONP)

0
  chco's Photo
Posted Jul 27 2010 08:39 PM

You want to query for data using a web service API, such as the Netflix API or Twitter’s API. However, the Ajax same-origin policy prevents cross-domain communication. Here is a way to resolve the issue in this excerpt from Javascript Cookbook.

The most commonly used technique to solve the cross-domain problem, and the approach I recommend, is to create a server-side proxy application that is called in the Ajax application. The proxy then makes the call to the other service’s API, returning the result to the client application. This is safe, secure, and very efficient, because we can clean the data before returning it to the Ajax application.

There is another approach: use JSONP (JSON, or Javascript Object Notation, with Padding) to workaround the security issues. I once used this approach to create a mashup between Google Maps and a Flickr query result:

function addScript( url) {
   var script = document.createElement('script');
   script.type="text/javascript";
   script.src = url;
   document.getElementsByTagName('head')[0].appendChild(script);


The URL looked like the following, including a request to return the data formatted as JSON, and providing a callback function name:

http://api.flickr.com/services/rest/?method=flickr.photos.search&user_id=xxx&api_ke
y=xxx&format=json&
jsoncallback=processPhotos


When the script tag is created, the request to Flickr is made, and since I passed in the request for a JSON formatted result and provided a callback function name, that’s how the return was provided. The callback string is similar to the following:

// assign photos globally, call first to load
function processPhotos(obj) {
  photos = obj.photos.photo;
  ...
}


The callback function would pass the data formatted as a JSON object in the function argument.

Ajax works within a protected environment that ensures we don’t end up embedding dangerous text or code into a web page because of a call to an external application (which may or may not be secure).

The downside to this security is that we can’t directly access services to external APIs, such Flickr, Twitter, and Google. Instead, we need to create a server-side proxy application, because server applications don’t face the cross-domain restriction.

The workaround is to use something like JSONP, demonstrated in the solution. Instead of using XMLHttpRequest, we convert the request URL into one that we can attach to a script’s src attribute, because the script element does not follow the same-origin policy. It couldn’t, or we wouldn’t be able to embed applications such as Google Maps into the application.

If the service is amenable, it returns the data formatted as JSON, even wrapping it in a callback function. When the script is created, it’s no different than if the function call is made directly in our code, and we’ve passed an object as a parameter. We don’t even have to worry about converting the string to a Javascript object.

It’s a clever trick, but I don’t recommend it. Even with secure services such as Flickr and Twitter, there is the remote possibility that someone could find a way to inject Javascript into the data via the client-side application for the service, which can cause havoc in our own applications.

It’s better to be smart then clever. Use a proxy application, scrub the result, and then pass it on to your client application.

Javascript Cookbook

Learn more about this topic from Javascript Cookbook.

Covering both ECMAScript 5 and HTML5, Javascript Cookbook helps you take advantage of the latest web features, including HTML5's persistent storage mechanisms and drawing canvas. You'll find solutions for integrating these features with Javascript into UIs that people will enjoy using. The recipes in this book not only help you get things done, they'll also help you develop applications that work reliably in every browser.

See what you'll learn


Tags:
0 Subscribe


0 Replies