Using JSONP with AngularJS

 

AngularJS’s $http service is capable of sending JSONP requests. The normal AJAX calls can only send requests to URLs within the same domain as the HTML page sending the requests was loaded from. You can get around this with JSONP requests.

JSONP is short for “JSON with Padding”  A JSONP request is not sent via the XHR object like AJAX calls normally are. Instead, a <script> element is created and inserted into the HTML page. Here is an example of how such a <script> element could look:

<script src="http://jenkov.com/theService.json?callback=theServiceResponse&p1=v1&p2=v2"></script>

The src attribute contains the URL of the remote service to call with the JSONP call. This URL should include any parameters you need to send to the remote service.

When the <script> element is inserted into the HTML page, the browser will load the script from the given URL. That enables the remote service to send JavaScript back to your application for execution.

The JavaScript returned by the remote service should be a function call to an existing JavaScript function in your HTML page. Here is how the returned JavaScript could look:

theServiceResponse( { name : "John", title : "CEO", company : "BigFatCo" } );

This code makes a function call to the function named theServiceResponse. This function must be present in your HTML page already. Inside this function you process the response sent back from the service.

When the theServiceResponse() function is called, a JavaScript object is passed to the function as parameter. This JavaScript object contains the response parameters from the service call. Thus, this JavaScript object is generated by the remote service. Whatever the remote service wants to send back to you is what this JavaScript object contains. Seen from the remote service’s perspective, that JavaScript object is just JSON like any other JSON sent back to an HTML page. The difference is that this JSON object is wrapped in a function call. This function call is the “padding” part of the “JSON with Padding” name for JSONP.

You might wonder how the remote service knows the name of the function to wrap the returned JSON in. The answer is, that you pass that name to the remote service along with the other request parameters. The function name is one of the request parameters. By default this parameter name is callback but you will have to check with the concrete service to see what parameter name it expects for the function name.

In AngularJS the function name is supplied behind the scene by AngularJS, so you don’t have to worry about adding it to the URL of the remote service.

You use JSONP calls via the $http service like this:

$http.jsonp( url, config );

Like with the AJAX functions the jsonp() function takes a url and a config object. Here is an example of a JSONP call with the url and config objects supplied:

var url = http://jenkov.com/theService.json?callback=JSON_CALLBACK";
var responsePromise = $http.jsonp( url,
             {  params : {
                   p1 : "v1"
                  ,p2 : "v2"
                }
              }
            );

responsePromise.success(function(data) {
    // do something with the returned JavaScript object
    // ( in the "data" parameter ).
});

This example makes a JSONP call to the service URL http://jenkov.com/theService.json. Like with the other AJAX functions of the $http service, the config object can contain a params field. This field should be a JavaScript object containing all the request parameters to append to the URL of the remote service.

When you call the $http.jsonp() function AngularJS will create <script> element for you, and insert it into your HTML page. AngularJS will also create the final URL of the remote service by appending the parameters passed in theconfig.params object to the URL.

The URL passed to the $http.jsonp() function must contain the callback=JSON_CALLBACK parameter. AngularJS will replace the JSON-CALLBACK string with the name of a callback function which AngularJS creates.

The promise object returned by the $http.jsonp() function has a success() function, just like the other AJAX function call promise objects. Unfortunately we do not have access to the HTTP headers of the response sent back from the server, since that request is handled by the browser internally, when evaluating the <script src="url">element. That also means that if the JSONP call fails, we have no way of knowing so, since no callback function will get called in that case (no JavaScript to execute from the remote service).

JSONP Security

You have to be careful with JSONP calls. When you make a JSONP call. The remote service could send back anyJavaScript which would then get executed inside your HTML page. An evil remote service could send back JavaScript which attempts to steal information from your application and sent it to a third party service. Only make JSONP calls to services you trust.

2 thoughts on “Using JSONP with AngularJS

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