Software Design Blog

Simple solutions to solve complex problems

JSON vs JSONP explained with detailed web request samples


What is JSONP?

JSONP (JSON with Padding) is a method commonly used to bypass the cross-domain policies in web browsers. You are not allowed to make AJAX requests to a web page perceived to be on a different server by the browser.  For example, if your domain is mydomain.com then your browser may prevent calling services on another domain such as otherdomain.com.

If you’re planning on making read-only (GET) requests to another domain, such as calling an Address Validation and Autocomplete API on your registration or checkout form, then JSONP is worth considering.

What is difference between JSON and JSONP?

Let’s look at the difference by starting with a JSON request first, calling the Addy address search service.  To run the example, replace “YOUR-API-KEY” with your own free API key from signing up to Addy, which only takes a minute.

JSON Request

GET https://www.addy.co.nz/api/search?key=YOUR-API-KEY&s=275+Queen+Street+Auckland HTTP/1.1
Host: www.addy.co.nz
contentType: "text/javascript"
JSON Response 
{"matched":1,"addresses":[{"id":1969683,"a":"275 Queen Street, Auckland Central, Auckland 1010"}],"badwords":[],"q":null}
As shown above, the client made a simple API call and received a JSON message in the response body. 

Let’s make a JSONP request. Notice that the main difference is that a callback query string with the name of a callback function was supplied in the request.

JSONP Request

GET https://www.addy.co.nz/api/search?key= YOUR-API-KEY&s=275+Queen+Street+Auckland&callback=setAddress HTTP/1.1
User-Agent: Fiddler
Host: www.addy.co.nz
contentType: "text/javascript"
JSONP Response 
setAddress({"matched":1,"addresses":[{"id":1969683,"a":"275 Queen Street, Auckland Central, Auckland 1010"}],"badwords":[],"q":null})
As shown above, the response message is wrapped in the name of the function we’ve supplied in the request. 

If we have a client side javascript function called setAddress(addresses) then the JSONP response will call the setAddress method and include the addresses response as a parameter.

JSONP Client Side Changes

In order for JSONP to work, you will need to modify your client side JavaScript calls to include a name of the callback function as a parameter.

JSONP Server Side Changes

By default, web services such as Web API doesn’t support JSONP out of the box.  An easy way to add JSONP support is to install the Jsonp NuGet Package:

Install-Package WebApiContrib.Formatting.Jsonp

Or the classic way of doing it is to create the JsonCallbackAttribute filter class as shown below, and register it in the WebApiConfig.Register method as:

config.Filters.Add(new JsonCallbackAttribute());

The  callback attribute class responsible for detecting and intercepting the JSONP request:

public class JsonCallbackAttribute : ActionFilterAttribute

{

  private const string CallbackQueryParameter = "callback";

 

  public override void OnActionExecuted(HttpActionExecutedContext context)

  {

    var callback = string.Empty;

 

    if (IsJsonp(out callback))

    {

      var jsonBuilder = new StringBuilder(callback);

      jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result);

      context.Response.Content = new StringContent(jsonBuilder.ToString());

    }

    base.OnActionExecuted(context);

  }

 

  private bool IsJsonp(out string callback)

  {

    callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter];

    return !string.IsNullOrEmpty(callback);

  }

}

Conclusion

Getting JSONP working is straight forward.  If you’d like a test service or want to explore how you can create a delightful checkout experience for your customers then I’d highly recommend using an online address autocomplete service such as Addy.