TL;DR
JSONP is an old trick invented to bypass a security restriction that forbids us to get JSON data from another server (origin*).
The trick works by using a <script>
tag that asks for the JSON from that place, e.g.: { "user":"Smith"}
, but wrapped in a function, the actual JSONP:
usePeopleData({"user":"Smith"})
Receiving it in that form enables us to use the data within our usePeopleData
function. JSONP is bad, don't use it (read below)
The problem
Say we're navigating on ourweb.com
, and we want to get JSON data (or any raw data really) from anotherweb.com
. If we were to use GET request (like XMLHttpRequest
, a fetch
call, etc.), our browser would tell us it's not allowed:

How to get the data we want? Well, <script>
tags are not subjected to this whole server (origin*) restriction! This allows us to load a library like jQuery or Google Maps from any server, such as a CDN.
Important point: now, those libraries are actual, runnable JS code (usually a big function with all the logic inside). But raw data, even in a correctly formatted JSON, is not code. There's nothing to run; it's just plain data.
Therefore there's no function name to call, no way to "handle" our precious data. The browser will download the data pointed at by our <script>
tag and when processing it'll complain:
wtf is this {"user":"Smith"}
crap we loaded? It's not code. Can't compute, syntax error!
The JSONP hack
The old/hacky way to get our data? We need that JSON data inside a JS function. The external file we load would look like this:
usePeopleData({"user":"Smith"})
which makes it JS code our browser will parse without complaining! To get it like that, we "ask" a JSONP-aware server for it, more or less like this:
<script src="https://web.com/api/peopleData?mycallback=usePeopleData"></script>
Our browser will be loading a JSONP with that function name, hence we need a function with the same name in our code, like this:
const usePeopleData = function(data){
alert(data.user);
};
So, the browser will download the JSONP line and run it, which will call our function, where the argument data
will be our JSON. We can now do with our data whatever we want to.
Don't use JSONP, use CORS
It's a cross-site scripting hack with a few downsides:
- We can only perform GET requests
- Since it's a GET request triggered by a simple script tag, we don't get helpful errors or progress info
- There are also some security concerns, like running in your client JS code that could be changed to a malicious payload
- It only half solves the problem from JSON data, but Same-Origin policy applies to any data (WebFonts, images/video drawn with drawImage()...)
- It's not very elegant nor readable.
The takeaway is that there's no need to use it nowadays.
JSONP is the trick to get JSON data from another service, but we'll violate the same security principle (Same-Origin) if we need other kind of cross-site stuff.
You should read about CORS here, but the gist of it is:
Cross-Origin Resource Sharing (CORS) is a mechanism that uses
additional HTTP headers to tell browsers to give a web application
running at one origin, access to selected resources from a different
origin. A web application executes a cross-origin HTTP request when it
requests a resource that has a different origin (domain, protocol, or
port) from its own.
*origin is defined by 3 things: protocol, port, and host. So, for example, https://web.com
is a different origin than http://web.com
(different protocol) and https://web.com:8081
(different port) and obviously https://thatotherweb.net
(different host)
0
Created by Carles Alcolea on 2020-03-07 14:03:44 +0000 UTC
Share