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.