When it comes to CORS, we consider JSONP also. This article will take you through each and every detail of JSONP and most importantly, why NOT to use them. Before going any further, I will start with the explanation of technical terms used here so that you don’t need any other reference material.
What is CORS?
CORS is acronym of Cross Origin Resource Sharing. Broadly, it means getting the data from different Web Servers. Two URLs are said to be from the same origin when they have identical schemes, hosts, and ports.
e.g.
- http://example.com/foo.html
- http://example.com/bar.html
But, these following URLs are NOT from same origin and any data sharing among them will come under Cross Origin Resource Sharing (CORS).
- http://example.net - Different domain
- http://example.com:9000/foo.html - Different port
- https://example.com/foo.html - Different scheme
- http://www.example.com/foo.html - Different subdomain
Getting more basic, when you create two projects in one solution, one is Web API and another is Web Client project, they will also be in Cross Origin as their URLs will be something like this,
- http://localhost:54150/
- http://localhost:54154/
So, to communicate between them, we will have to EnableCORS (How to do that is not within the scope of this article :P ).
I hope I was able to explain the concept of CORS properly.
What is JSONP?
JSONP means JSON with Padding and JSON stands for Java Script Object Notation. Exact definition of JSONP goes like this.
"JSONP is script tag injection, passing the response from the Server in to a user specified function."
Not very clear ? Don’t worry ! Even I couldn’t understand much with this but focus on the 3 groups of 3 magical words underlined above. I will come back to them again to show you the actual magic.
How JSONP Works?
Don’t panic. I promise after these few lines, you will understand actually what JSONP is and how it works.
In your web page, you have seen many references to different CDNs for jQuery, AngularJS, and/or many JS frameworks, like this.
Some of them are to Google, Microsoft and others. Of course, they are NOT in the same origin you are requesting from and we don’t get any error in downloading those files. Right? So, it means, in script tag, you can have CORS without any issue and JSONP takes the benefit.
Now, suppose we are making a call to get some data from the server. The jQuery code will be something like this.
And, we will get a JSON response like this.
- {"FirstName": "Atul","LastName": "Sharma","Profile": "Programmer"}
But, if I am making the same request with JSONP, my code will look like this.
Notice 2 changes here.
- Callback Function in $.ajax
- Data type as JSONP
So, here we are passing our response from Server to another function named callbackReturn() with JSONP data type.
Let’s examine what response we are getting in this scenario.
Surprise -- I got response from the Server as,
- callbackReturn({"FirstName":"Atul","LastName":"Sharma","Profile":"Programmer"});
So now, it will call callbackReturn() function with Server response and this function will further the process, the same as per our business requirement.
Now again, I am coming back to the definition of JSONP.
- JSONP is script tag injection (callbackReturn({"FirstName": "Atul","LastName": "Sharma","Profile": "Programmer"}); as this is in script tag only)
- passing the response from the server ({"FirstName": "Atul","LastName": "Sharma","Profile": "Programmer"})
- in to a user specified function (callbackReturn() function)
So, here I am assuming that I explained properly what JSONP actually is and how it works.
Why JSONP is NOT considered good for CORS
- It can be only applied to HTTP GET method, as only GET method is supported by script tag.
- Since this relies on script tag only, there is no universal way to catch errors. Some browsers will allow attaching a callback to the script tag (e.g. onError() { … }), but it is NOT universally supported.
If the called API is doing syntactically correct things like returning an HTTP 404 response code when a resource cannot be found, there is no way to easily catch that error condition or parse the response body for further information.
- JSONP is really a security vulnerability.
References
- https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
- https://johnnywey.wordpress.com/2012/05/20/jsonp-how-does-it-work/