JSONP made easy in ASP.NET AJAX

The latest release of the MS AJAX library adds support for making JSONP calls. JSONP (aka JSON with padding) can be seen as a standard for getting JSON from remote domains. As you probably know by now, external communications from the the browser to a server are limited to the “current” domain (for improved security). This means that you can use the XMLHttpRequest object to get out-of-band data from your domain but you’re out of luck if you need info from a third-party domain.

There are some solutions for this problem. For instance, you can create a web service which acts like a proxy. You could then make all the calls go through that local service and that’s enough for transforming an external call into a local call (the problem is that you’re duplicating the remote service). You can also use plugins for solving this problem. For instance, Flash and Silverlight allow remote external calls (though you need to set up a policy file).

The last solution relies in the use of the SCRIPT tag. The SCRIPT tag lets you load external scripts (ie, scripts from a different domain from the one that is hosting your page). If instead of a SCRIPT file you’ve got a service which returns JSON, then that JSON will be returned and parsed as JavaScript. Now, the problem of this approach is that you can’t simply return a JavaScript instruction. For instance, returning something like this doesn’t really do anything useful:

{ ‘name’: ‘luis’ }

At the minimum, it will have to introduce a variable in the page so that you can reference it later:

var result = { ‘name’: ‘luis’ };

Even though this works, it’s not really recommended. For starters, it’s polluting the global namespace. This means that you need to make sure that you’re not using any variable with that name (if you had one, then the previous instruction will simply overwrite it with the new value). Besides this problem,there’s still the notification part…I’m guessing that you’ll probably will want to get notified when the results returned are ready for consume,right?

And this is why JSONP was “invented”. The idea is to add flexibility to this kind of calls. Wouldn’t it be a lot better if we could specify the name of callback method which receives the results obtained through the evaluation of the returned from the server? Yes, this would involve collaboration between client and server, but it’s not that complicated. The client would need to use a specific parameter for indicating the name of the callback function (done by adding a specific parameter to the query string of the specified URL). On the other hand, the server would need change the JavaScript it returns: instead of introducing a variable, it would need to call the function the client specified through the parameter. In other words, the returned JS would look something like this:

someMethod( { ‘name’: ‘luis’ } );

you can already do all of this “by hand”. For instance, the preview 5 of MS AJAX has a sample (folder JSONP) which shows the code you need to interact with a JSONP service. As you can see, you’ll need to add a script node and interact with the page’s DOM. It’s not really complicated, but you still need some lines of code just for “calling” the service.

The good news is that the MS AJAX WebServiceProxy class has been upgraded and now you can run some JSONP calls by using its static invoke method (internally, it takes care of all those nifty details for you – isn’t that great?). To show you its use, I’m going to update that JSONP sample so that it uses the invoke method call. Here’s the improved JS code (I’m only showing the JS code, so you’ll have to add it to your JSONP.html page to test it):

function pageLoad() {
    queryPopularLinksForTag("viewstate");

    $addHandler($get("tag"), "keydown",
        function(e) {
            if (e.keyCode === Sys.UI.Key.enter) {
                e.preventDefault();
                queryPopularLinksForTag($get("tag").value);
            }
        });

    $addHandler($get("go"), "click",
        function(e) {
            queryPopularLinksForTag($get("tag").value);
        });
}

function queryPopularLinksForTag(tag) {
    var url = “http://feeds.delicious.com/v2/json/popular/
+ encodeURI(tag); Sys.Net.WebServiceProxy.invoke(url, null, true, null, function(results) { $find("dataView").set_data(results); }); }

The most important code is on the queryPopularLinksForTag function. Before we go on, you’ll probably need to understand the URL expected by the service. it’s on the form: http://feeds.delicious.com/v2/json/popular/key_words?callback=cbMethodName, where *callback* identifies the function that will be called.

As you can see, we’re not specifying the callback in the query string of the URL. And we’re not doing it because the invoke method will automatically do that for us. It will add its own method, which will then redirect the response to the succeeded method you’ve passed. If you’ve used the WebServiceProxy class’ invoke method in the past, you probably know that it supports more parameters (which we didn’t use in the previous snippet). Here’s its current signature:

function Sys$Net$WebServiceProxy$invoke(servicePath, 
methodName,
useGet,
params,
onSuccess,
onFailure,
userContext,
timeout,
enableJsonp,
jsonpCallbackParameter)

There are two new parameters (enableJsonp and jsonpCallbackParameter) which are important for our current discussion. We didn’t set the enableJsonp parameter to true because, internally, the invoke method will compare the URL with the current domain and will default to JSONP when it detects a request to a different domain.

We didn’t use the jsonCallbackParameter either because the default parameter name (ie, the parameter used in the query string to specify the name of the callback function) is the same as the one expected by the delicious service: callback (http:://…..?*callback*=somemethod). If, for instance, the delicious JSONP service expected the parameter’s name to be cb (instead of callback), then we would need to pass that value to the jsonpCallbaclParameter parameter. That wouldn’t be great because we’d need to pass defaults for the parameter values we aren’t using, but that’s simply how it works now (I think this can be improved a little bit, so let’s hope MS improves the API of this method).

And I guess this sums it up quite nicely. More about MS AJAX in future posts.

Advertisements

~ by Luis Abreu on October 13, 2009.

2 Responses to “JSONP made easy in ASP.NET AJAX”

  1. TMEWFw imzxvwrkwncv, [url=http://fgkdppunhvhe.com/]fgkdppunhvhe[/url], [link=http://fgsypmymdkdm.com/]fgsypmymdkdm[/link], http://tvimjpzczdsc.com/

  2. levitra [url=”http://www.levitraguidance.com/”]levitra[/url] http://www.levitraguidance.com/ gebvup

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: