I understand JSON, but not JSONP. Wikipedia's document on JSON is (was) the top search result for JSONP. It says this:

JSONP or "JSON with padding" is a JSON extension wherein a prefix is specified as an input argument of the call itself.

Huh? What call? That doesn't make any sense to me. JSON is a data format. There's no call.

The 2nd search result is from some guy named Remy, who writes this about JSONP:

JSONP is script tag injection, passing the response from the server in to a user specified function.

I can sort of understand that, but it's still not making any sense.


So what is JSONP? Why was it created (what problem does it solve)? And why would I use it?


Addendum: I've just created a new page for JSONP on Wikipedia; it now has a clear and thorough description of JSONP, based on jvenema's answer.

42 upvote
  flag
Skaffman, do I take it then from your looking-down-the-nose tone that you are the one who removed the perfectly reasonable questions from WIKIpedia? Without adding anything or improving it? How is it "vandalism" to ask a question. Sheesh. And yes, at this very moment I am going to improve the wikipedia page, with the information that jvenema provided. – Cheeso
18 upvote
  flag
Great, if you have better info, then add it. But you don't ask questions on wikipedia, you add facts. – skaffman
13 upvote
  flag
For the record, do NOT use JSONP if you don't trust the server you're talking to 100%. If it is compromised, your webpage will be trivially compromised. – ninjagecko
4 upvote
  flag
Also note that JSONP can be hijacked if not implemented correctly. – Pacerier
1 upvote
  flag
I would like to give credit to the author of JSONP who gave the philosophy behind it: Bob Ippolito's archive on JSONP. He introduces JSONP as "a new technology agnostic standard methodology for the script tag method for cross-domain data fetching". – harshvchawla
2 upvote
  flag
Why is this question tagged as a duplicate when the question this is a "duplicate" of was asked 10 months after this one? – jvenema

7 Answers 11

Because you can ask the server to append a prefix to the returned JSON object. E.g

function_prefix(json_object);

in order for the browser to eval "inline" the JSON string as an expression. This trick makes it possible for the server to "inject" javascript code directly in the Client browser and this with bypassing the "same origin" restrictions.

In other words, you can have cross-domain data exchange.


Normally, XMLHttpRequest doesn't permit cross-domain data-exchange directly (one needs to go through a server in the same domain) whereas:

<script src="some_other_domain/some_data.js&prefix=function_prefix>` one can access data from a domain different than from the origin.


Also worth noting: even though the server should be considered as "trusted" before attempting that sort of "trick", the side-effects of possible change in object format etc. can be contained. If a function_prefix (i.e. a proper js function) is used to receive the JSON object, the said function can perform checks before accepting/further processing the returned data.

up vote 1732 down vote accepted

It's actually not too complicated...

Say you're on domain example.com, and you want to make a request to domain example.net. To do so, you need to cross domain boundaries, a no-no in most of browserland.

The one item that bypasses this limitation is <script> tags. When you use a script tag, the domain limitation is ignored, but under normal circumstances, you can't really do anything with the results, the script just gets evaluated.

Enter JSONP. When you make your request to a server that is JSONP enabled, you pass a special parameter that tells the server a little bit about your page. That way, the server is able to nicely wrap up its response in a way that your page can handle.

For example, say the server expects a parameter called "callback" to enable its JSONP capabilities. Then your request would look like:

http://www.example.net/sample.aspx?callback=mycallback

Without JSONP, this might return some basic JavaScript object, like so:

{ foo: 'bar' }

However, with JSONP, when the server receives the "callback" parameter, it wraps up the result a little differently, returning something like this:

mycallback({ foo: 'bar' });

As you can see, it will now invoke the method you specified. So, in your page, you define the callback function:

mycallback = function(data){
  alert(data.foo);
};

And now, when the script is loaded, it'll be evaluated, and your function will be executed. Voila, cross-domain requests!

It's also worth noting the one major issue with JSONP: you lose a lot of control of the request. For example, there is no "nice" way to get proper failure codes back. As a result, you end up using timers to monitor the request, etc, which is always a bit suspect. The proposition for JSONRequest is a great solution to allowing cross domain scripting, maintaining security, and allowing proper control of the request.

These days (2015), CORS is the recommended approach vs. JSONRequest. JSONP is still useful for older browser support, but given the security implications, unless you have no choice CORS is the better choice.

144 upvote
  flag
Please note that using JSONP has some security implications. As JSONP is really javascript, it can do everything else javascript can do, so you need to trust the provider of the JSONP data. I've written som blog post about it here: erlend.oftedal.no/blog/?blogid=97 – Erlend
62 upvote
  flag
Is there really any new security implication in JSONP that is not present in a <script> tag? With a script tag the browser is implicitly trusting the server to deliver non-harmful Javascript, which the browser blindly evaluates. does JSONP change that fact? It seems it does not. – Cheeso
20 upvote
  flag
Nope, it doesn't. It you trust it to deliver the javascript, same thing applies for JSONP. – jvenema
14 upvote
  flag
It's worth noting that you can ramp up security a little by changing how the data is returned. If you return the script in true JSON format such as mycallback('{"foo":"bar"}') (note that the parameter is now a string), then you can parse the data manually yourself to "clean" it before evaluating. – jvenema
2 upvote
  flag
@Cheeso: No it's the exact same problem. But some people fail to realize that this is a problem. @jvenema: You would still have to trust the provider of the data :-) – Erlend
1 upvote
  flag
@Erlend, no disagreement - any time you're loading something cross-domain, you'll have to have at least some trust in what you're loading :) – jvenema
upvote
  flag
@jvenema CURL is also developed for cross domain data retrivation ( AFAIK) then what is the need of JSONP? – JustLearn
8 upvote
  flag
CURL is a server-side solution, not client-side. They serve two different purposes. – jvenema
3 upvote
  flag
{ foo: 'bar' } is completely legit as a JS object literal, which is what my example showed - JSONP works fine with object literals or strict JSON. – jvenema
5 upvote
  flag
@Stephen { 'foo' : 'bar' } is still not valid JSON. Double-quotes are required. – Joe Coder
1 upvote
  flag
@Cheeso - difference is <script> tags would tend refer to a resource under your own control. E.g. if you don't trust a CDN just copy the script to your own server. That option is not possible with JSONP if you want the data to go from a server you don't directly control directly to the web page. jvenema's workaround is a good idea though. – Martin Capodici
upvote
  flag
@Quentin - some good thoughts in your edit, but they change some of the simplicity and explicitness of the original answer. I've added an edit that references CORS as an option as well. – jvenema
upvote
  flag
I think JSONRequest is a red herring, as far as I know there aren't any browsers that support it. – Quentin
upvote
  flag
It's also weird to give all the non-JSONP examples as fragments of JavaScript instead of JSON since people usually are using JSON already (especially if they are considering JSONP). – Quentin
upvote
  flag
Come to think of it, your example of JSONP isn't even JSONP. It's just JavaScript, but the function argument is invalid JSON. It'll work in most cases, but not for the occasional JSONP parser that strips off the callback stuff and then passes the rest to a JSON parser. – Quentin
upvote
  flag
So callback=? means we assign the wrapper name on the server correct? I thought we were passing a unique identifier for determining page instances or something but this makes much more sense. Great post! – yardpenalty
upvote
  flag
Correct. Since the js is simply executed by the browser immediately when the response is received, you have to tell the server what function (in the browser) you want to be invoked, and the server is responsible for wrapping the data up so it invokes that function. – jvenema
upvote
  flag
@Quentin - see the comments at the beginning of the thread re: JSON vs JS literals. – jvenema
upvote
  flag
so basically you can just move on without really knowing how it works right?.. – Matian2049
upvote
  flag
it's worth pointing out that , returned script is not allowed to mess with your DOM. That's why you pass your own function name which you have reference to. – Cholthi Paul Ttiopic
2 upvote
  flag
@CholthiPaulTtiopic — JSONP works by injecting a script into the page. The returned script can mess with the DOM as much as it likes. JSONP opens you up to XSS attacks from the data source, so you must trust the data source completely. (Which is why CORS is better, it doesn't suffer from this problem). – Quentin
1 upvote
  flag
@yardpenalty — Not quite. callback=? means the wrapper name is determined by a client-side library which will replace the ? with something random to avoid conflicts (since the function that gets called has to be a global). The server is then expected to use the function name the ? is replaced with when it generates the callback. – Quentin
upvote
  flag
@Quentin thanks. So we can effectively say the callback you give opens the security doors to the datasource developers. – Cholthi Paul Ttiopic
upvote
  flag
@CholthiPaulTtiopic yes! hence the massively upvoted comment about security – jvenema
upvote
  flag
@Quentin how dangerous java-script injected through function argument can get, Is this not limited only to data and not excutable JS – Cholthi Paul Ttiopic
upvote
  flag
@CholthiPaulTtiopic — "how dangerous java-script injected through function argument can get" — It fully exposes you to any JS that the site wants to send. "Is this not limited only to data and not executable JS" — No, it isn't. You can put any expression you like in a function argument. alert( function() { do_bad_stuff(); return "xss" }() );. Even if that wasn't the case, you're loading a script from a third party. They don't have to send you one that matches the conventions of JSONP. It doesn't have to mention your callback. It could just be an plain attack script. – Quentin
upvote
  flag
@Quentin woah ! does the JSONP library just echo everything into script tag before making sure a valid callback is supplied by the data source. That w'd be vanilla cross-domain request in action. – Cholthi Paul Ttiopic
upvote
  flag
@CholthiPaulTtiopic — No. In order to do that it would have to be able to read the script as plain text using XHR. The whole point of JSONP is to hack around that. The client library (1) Injects a function with a random name such as YOUR_CALLBACK (2) Injects <script src="http://example.com/jsonp?callback=YOUR_CALLBACK"></scri‌​pt> – Quentin
1 upvote
  flag
I see the conventions of JSONP are designed around convenience rather than security – Cholthi Paul Ttiopic
upvote
  flag
@jvenema kudos for the explanation! – Ayhan Dorman
upvote
  flag
I guess I am not clear on the above. The answer says the other server will return some response. But how does the server call gets across in the first place. (as the answer itself says xyz.com can't connect to xyz.net) – Saurabh Tiwari
upvote
  flag
Normally xyz.com can't talk to xyz.net. JavaScript <script> tags bypass that restriction. – jvenema
upvote
  flag
But if that source you are referring to is malicious, shouldn't without JSONP, still it could send suppose i have <script src="somesite.com/hacked.js" >, now this js file that we take from other source could also pretty much do anything that JSONP does, am it right, and if that so, then why JSONP is getting so much popularity, shouldn't we just not include resources from SITE we do not trust, as without JSONP also it can just send a simple js file that can access our whole DOM. Please clear my confusion – Suraj Jain

JSONP is really a simple trick to overcome the XMLHttpRequest same domain policy. (As you know one cannot send AJAX (XMLHttpRequest) request to a different domain.)

So - instead of using XMLHttpRequest we have to use script HTML tags, the ones you usually use to load js files, in order for js to get data from another domain. Sounds weird?

Thing is - turns out script tags can be used in a fashion similar to XMLHttpRequest! Check this out:

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data';

You will end up with a script segment that looks like this after it loads the data:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

However this is a bit inconvenient, because we have to fetch this (object containing an) array from script tag. So JSONP creators decided that this will work better(and it is):

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data?callback=my_callback';

Notice the my_callback function over there? So - when JSONP server receives your request and finds callback parameter - instead of returning plain js object/array it'll return this:

my_callback({['some string 1', 'some data', 'whatever data']});

See where the profit is: now we get automatic callback (my_callback) that'll be triggered once we get the data.
That's all there is to know about JSONP: it's a callback and script tags.

NOTE: these are simple examples of JSONP usage, these are not production ready scripts.

Basic JavaScript example (simple Twitter feed using JSONP)

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p>' + '<img src= ' + "twitterEntry.user.profile_image_url_https" + '/>' + twitterEntry + '</p>';
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>

Basic jQuery example (simple Twitter feed using JSONP)

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p>' + '<img src = ' + "twitterEntry.user.profile_image_url_https" + '/>' + twitterEntry + '</p>';
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONP stands for JSON with Padding. (very poorly named technique as it really has nothing to do with what most people would think of as “padding”.)

30 upvote
  flag
Thanks for the script tag explanation. I wasn't able to figure out how the cross domain security policy was bypassed by JSONP. After the explanation I feel a litte stupid to miss the point... – Eduard
13 upvote
  flag
This is a very good complementary answer to jvenema's answer - I didn't understand why the callback was necessary until you pointed out that the json data would otherwise have to be accessed via the script element. – Matt
upvote
  flag
Feeling awesome after knowing that Script tag work as XMLHttp :-) Thanks for nice explanation – ravisoni
upvote
  flag
@ravisoni how does ie6 load scripts then? activeX? – FutuToad
3 upvote
  flag
Thanks for such lucid explanation. I wish my college textbooks were written by people like you :) – hashbrown
upvote
  flag
Hi ThatGuy, your answers is really helpful for me, thanks a lot, but i have only one doubt, in the jQuery example again you are using ajax method which internally calls XMLHttpRequest, which again will give cross domain issues, is that correct ? – John
1 upvote
  flag
Good explication rather than the previous one. Ofcourse- your excerpt " the ones you usually use to load js files, in order for js to get data from another domain. Sounds weird?" is also eye opener for me. Example code in very much illustrious. – SIslam
upvote
  flag
Great explanation, but when I tried the first example, I got this error : "Failed to load resource: the server responded with a status of 404 (OK)" How can I get around it? – Humoyun
upvote
  flag
This was really helpful. In addtion, how the heck do i adjust the Accept Header to tell my 3rd party server what to respond with. It seems impossible to set Headers when doing datatype json. – Kirby

JSONP works by constructing a “script” element (either in HTML markup or inserted into the DOM via JavaScript), which requests to a remote data service location. The response is a javascript loaded on to your browser with name of the pre-defined function along with parameter being passed that is tht JSON data being requested. When the script executes, the function is called along with JSON data, allowing the requesting page to receive and process the data.

For Further Reading Visit: https://blogs.sap.com/2013/07/15/secret-behind-jsonp/

client side snippet of code

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <title>AvLabz - CORS : The Secrets Behind JSONP </title>
     <meta charset="UTF-8" />
    </head>
    <body>
      <input type="text" id="username" placeholder="Enter Your Name"/>
      <button type="submit" onclick="sendRequest()"> Send Request to Server </button>
    <script>
    "use strict";
    //Construct the script tag at Runtime
    function requestServerCall(url) {
      var head = document.head;
      var script = document.createElement("script");

      script.setAttribute("src", url);
      head.appendChild(script);
      head.removeChild(script);
    }

    //Predefined callback function    
    function jsonpCallback(data) {
      alert(data.message); // Response data from the server
    }

    //Reference to the input field
    var username = document.getElementById("username");

    //Send Request to Server
    function sendRequest() {
      // Edit with your Web Service URL
      requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+"");
    }    

  </script>
   </body>
   </html>

Server side piece of PHP code

<?php
    header("Content-Type: application/javascript");
    $callback = $_GET["callback"];
    $message = $_GET["message"]." you got a response from server yipeee!!!";
    $jsonResponse = "{\"message\":\"" . $message . "\"}";
    echo $callback . "(" . $jsonResponse . ")";
?>
3 upvote
  flag
the link at the top just 404s now – Kevin Beal
upvote
  flag

JSONP is a great away to get around cross-domain scripting errors. You can consume a JSONP service purely with JS without having to implement a AJAX proxy on the server side.

You can use the b1t.co service to see how it works. This is a free JSONP service that alllows you to minify your URLs. Here is the url to use for the service:

http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]

For example the call, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

would return

whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});

And thus when that get's loaded in your js as a src, it will automatically run whateverJavascriptName which you should implement as your callback function:

function minifyResultsCallBack(data)
{
    document.getElementById("results").innerHTML = JSON.stringify(data);
}

To actually make the JSONP call, you can do it about several ways (including using jQuery) but here is a pure JS example:

function minify(urlToMinify)
{
   url = escape(urlToMinify);
   var s = document.createElement('script');
   s.id = 'dynScript';
   s.type='text/javascript';
   s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
   document.getElementsByTagName('head')[0].appendChild(s);
}

A step by step example and a jsonp web service to practice on is available at: this post

2 upvote
  flag
Thanks for posting your answer! Please note that you should post the essential parts of the answer here, on this site, or your post risks being deleted See the FAQ where it mentions answers that are 'barely more than a link'. You may still include the link if you wish, but only as a 'reference'. The answer should stand on its own without needing the link. – bluefeet

A simple example for the usage of JSONP.

client.html

    <html>
    <head>
   </head>
     body>


    <input type="button" id="001" onclick=gO("getCompany") value="Company"  />
    <input type="button" id="002" onclick=gO("getPosition") value="Position"/>
    <h3>
    <div id="101">

    </div>
    </h3>

    <script type="text/javascript">

    var elem=document.getElementById("101");

    function gO(callback){

    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://localhost/test/server.php?callback='+callback;
    elem.appendChild(script);
    elem.removeChild(script);


    }

    function getCompany(data){

    var message="The company you work for is "+data.company +"<img src='"+data.image+"'/   >";
    elem.innerHTML=message;
}

    function getPosition(data){
    var message="The position you are offered is "+data.position;
    elem.innerHTML=message;
    }
    </script>
    </body>
    </html>

server.php

  <?php

    $callback=$_GET["callback"];
    echo $callback;

    if($callback=='getCompany')
    $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})";

    else
    $response="({\"position\":\"Development Intern\"})";
    echo $response;

    ?>    

Before understanding JSONP, you need to know JSON format and XML. Currently the most frequently used data format on the web is XML, but XML is very complicated. It makes users inconvenient to process embedded in Web pages.

To make JavaScript can easily exchange data, even as the data processing program, we use the wording according to JavaScript objects and developed a simple data exchange format, which is JSON. JSON can be used as data, or as a JavaScript program.

JSON can be directly embedded in JavaScript, using them you can directly execute certain JSON program, but due to security constraints, the browser Sandbox mechanism disables cross-domain JSON code execution.

To make JSON can be passed after the execution, we developed a JSONP. JSONP bypass the security limits of the browser with JavaScript Callback functionality and the < script > tag.

So in short it explains what JSONP is, what problem it solves (when to use it).

2 upvote
  flag
I downvoted this because I don't believe the statement that XML was the most used dat format on the web in Dec '15. – RobbyD

Not the answer you're looking for? Browse other questions tagged or ask your own question.