Sunday, February 17, 2013

Cross-domain AJAX calls with JSONP


It's a common issue to have a web application running on a server that needs to make a web service call to a service running on another server. There are a couple of solutions to that:
  1. Make a direct HTTP GET call with server side code to the service:  
    • Pro: No special processing of the JSON return data: make the HTTP GET call, process the JSON response, display the data
    • Con: This is limited, as the page being returned is static
  2. Make an AJAX call with client side code to the service:  
    • Pro: Dynamically make the service call based on user interaction
    • Con: The application needs to have specialized handling to make the cross-domain AJAX request
For this discussion, we'll look deeper at the second bullet and explore the solution further.

Cross-Domain AJAX calls with JSONP
Without properly setting things up to make cross-domain AJAX calls, you might see the following if using Firebug.  You might see the following and wonder what the heck is going on?
  • Firebug shows a HTTP OK 200 response, which makes it appear that the call was successful.  But on closer inspection, there's no data returned in the response...
  • Firebug shows that data was returned, but it says the JSON is invalid.  When checking the JSON data in jsonlint, it's perfectly valid JSON!
JSONP (JSON with padding) can help us implement this more appropriately, but there are a couple of caveats:

Caveat 1: You have to be in control of the web application that is making the AJAX request:
    • That is because you need to specify to the web service that you want to wrap the response as JSONP.  
    • If using jQuery (since version 1.2), you can load JSON data located on another domain if you specify a JSONP "callback" URL parameter.
/webapp/service/com/blogspot/cherryshoe/docList?id=06022012&callback=?

Caveat 2: You have to be in control of the web service that is being called:
    • That is because you need to look for that optional "callback" parameter; if it's available, wrap the response as JSONP.
    • If using jQuery, jQuery will automatically assign the "callback" parameter a value, in this case it was "jQuery16406082620163990349_1361055846009", the web service will wrap the JSON response with that value, making it JSONP.
jQuery16406082620163990349_1361055846009
(
    {
        "status" : true,
        "statusMessage" : "Retrieved 2 documents for id: 06022012",
        "totalRecords" : 2,
        "documents" : 
        [
        {
            "docId" : "1234",
            "docName" : "06022012_1.pdf",
            "docType" : "1"
        },
        {
            "docId" : "5678",
            "docName" : "06022012_2.pdf",
            "docType" : "2"
        }
        ]
    }
)

Obviously there may be security considerations if the web service or web application is not public.  This article helped a lot when I was researching this issue.

No comments:

Post a Comment

I appreciate your time in leaving a comment!