Saturday, June 16, 2012

OData : Cross domain OData request using jQuery, JSONP

I've been doing a POC where I had a situation to make a request to a OData Service (service which exposed the data as OData  - Open Data Protocol) using jQuery. During my initial attempt, I got an error from the web browser which is due to the same origin policy of the web browser.  Usually Client side (request from browser using javascript) cannot be allowed to make a request to a resource that exists in another domain of which HTML <script> element is an exception. In such cases JSONP (JSON with padding) and CORS (Cross Origin Resource Sharing) is made use. Among the two, JSONP requests are commonly used right now and CORS is expected to catch the mass. In this post we'll focus on the JSONP model request for OData Service.

To get a quick idea on the need for JSONP and how that stuff works, please have a quick glimpse here.  The code snippets I represent in this post will use the Nerd Dinner OData Feed for easier understanding.

After deciding to make the JSONP request, I used jQuery.ajax() method with url : http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json & jsonpCallback option which resulted in error. Upon analyzing it, found out the error is "Uncaught SyntaxError: Unexpected token : " and the error is because the returned data is a simple JSON format and not wrapped with the callback method which is expected. Then I searched and found out the right format to make the OData JSONP request. The option is available as a OData query $callback.

Following are the three different alterations we can do to make a cross domain OData request using jQuery and JSONP.

Snippet 1:

$(document).ready(function () {

    $.ajax({
        url: 'http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json&$callback=nerdCallback',
        dataType: "jsonp"
    });
});

function nerdCallback(result) {
    //Manipulate the resultant here....
    alert("Result count : " + $(result["d"]["results"]).length);
}

Snippet 2:

$(document).ready(function () {

    $.ajax({
        url: 'http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json&$callback=?',
        dataType: "jsonp",
        jsonpCallback: "nerdCallback"
    });
});

function nerdCallback(result) {
    //Manipulate the resultant here....
    alert("Result count : " + $(result["d"]["results"]).length);
}

Snippet 3:

$(document).ready(function () {

    $.ajax({
        url: 'http://www.nerddinner.com/Services/OData.svc/Dinners?$format=json&$callback=?',
        dataType: "jsonp",
        success: function (result) {
            //Manipulate the resultant here....
            alert("Result count : " + $(result["d"]["results"]).length);
        }
    });
});

References:
http://en.wikipedia.org/wiki/JSONP
http://msdn.microsoft.com/en-us/library/ee834511.aspx
http://www.odata.org/
Creative Commons License
This work by Tito is licensed under a Creative Commons Attribution 3.0 Unported License.