JSON with Padding

JSONP is a trick to defeat the Same Origin Policy for the purpose of writing mash-ups.  In order for JSONP to work, both the client (your AJAX code) and the remote server (Google, Yahoo, Microsoft, etc) must support JSONP.

JSONP is "with padding" because it wraps JSON in a function call.  For example, the following might be returned from the third-party server:

clientSideCallback ({"key" : "value"});

Notice that the parameter to clientSideCallback is just a JavaScript object in JSON.  The clientSideCallback is a function you define in JavaScript on the client.  Since the server must return the name of the callback function, the server must know about your callback function.  Typically this is done via standardization (server will always wrap JSON in a special function) or by passing the name of the function to the server as part of the request.

For example, the Flickr API allows you to specify which function the server should pad JSON with:

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

The jsoncallback parameter is used to specify the name of the callback function.  If you click the above link, the server will respond with JSON padded with a call to myFunctionName.

What does the callback do?

When your browser is done retrieving the JSONP from the third-party server, it will automatically execute the JSONP.  Since it is a function call, your client-side function will be called with JSON as a parameter.  This will allow your AJAX to see the JSON returned from the server.

But How Does This Defeat the SOP?

Even if you use JSON with padding, you still cannot make an XMLHttpRequest to a third-party server due to the SOP.  However, you can use <script> tags to link to scripts on other sites (see AJAX Examples).  Since JSONP is a statement and not an expression in JavaScript, it can be executed as a remote script (rather than loaded as an object).

To do this, simply create a dynamic <script> node whenever your page needs to access data on a third-party site.  For example, you could dynamically create the following tag:

<script language='JavaScript' src='http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=clientSideCallback'></script>

...which would cause your browser to download and execute the JSONP.  When the data is downloaded, clientSideCallback will automatically be called.

Your clientSideCallback function might look something like:

function clientSideCallback (json) {

    alert ("downloaded " + json ["title"] + " from third-party site");

}

Comments