Skip to Content
Author's profile photo Former Member

Secret Behind JSONP

Understanding Your Browser :

     As we might be aware that Browser Security Model is considered as the weakest component for the current generation of AJAX and majorly considered as blockage for innovation.

     An attacker from anywhere in the world can insert a script on to your webpage and track all your sensitive details as he might be seeing what you are seeing. The root cause for this sort of script injection is because your damn browser which allows this to happen and barely anything can be done by users and developers to prevent such attack.

     Due to the poor design of security model from the browser vendors, Developers are also a victim. As developers just look around for a solution to get rid of this mess but it’s merely impossible to find a solution rather developers use this technique as a weapon to resolve Access Origin issue and share data via multiple origin’s.

This might sound really weird for most but that’s the truth behind JSONP technique.

So How Does JSONP Works ?

     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 the requested JSON data. When the script executes, the function is called along with JSON data, allowing the requesting page to receive and process the data.

This loop hole of inserting the “script” from server side dynamically at run time is the secret behind JSONP technique.

It’s time to code..

Let’s create a function which accepts the URL as the parameter and constructs the script tag at runtime and inserting the source from the remote server. In JSONP each script tag inserted is an individual AJAX call this might lead to unnecessary consumption of memory so once the data is consumed we would remove the script tag dynamically.


function requestServerCall(url) { //Construct the script tag at Runtime
  var head = document.head;
  var script = document.createElement("script");
  script.setAttribute("src", url);
  head.appendChild(script);
  head.removeChild(script); // remove the script tag once inserted to avoid memory consumption
}

By inserting the script tag at run time we basically do a web service call to server via GET method only.

1

The web service URL comprises of the predefined callback function along with additional parameters.

Let’s build the complete client side snippet of code

<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() {
    requestServerCall("http://localhost/myService.php?callback=jsonpCallback&message="+username.value+"");
    }   
    
  </script>
</body>
</html>

Almost we are done with client side portion of the code, let’s go ahead and write the server side code on PHP which consume the data from the URL like a GET request from client and responses back along with corresponding callback function with JSON data appropriate to the client side request.

Let’s understand the Server side piece of PHP code

    header("Content-Type: application/javascript");

    $callback = $_GET["callback"];

    $message = $_GET["message"]." you got a response from server yipeee!!!";

    $jsonResponse = "{\"message\":\"" . $message . "\"}";

    echo $callback . "(" . $jsonResponse . ")";


First, the header() function is used to set the MIME type to “application/javascript”. This tells the client to treat the response as JavaScript. “callback” and “message“ variables hold the parameters passed from client. Finally the appropriate JSON string is constructed and echoed back to client.

That sum’s the topic on JSONP on your local development environment.

Points to Remember:

  • JSONP bypasses the restrictions of the same origin policy by dynamic script injection.
  • Its handy solution if the data flow is insensitive.
  • The callback function’s name is passed to the web service as a parameter.

Final Words:

Hope this piece of information helped you understand JSONP and its behind the scene secrets..Happy Coding :)

Follow me @ www.avlabz.com









Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo DJ Adams
      DJ Adams

      Hi Ajain

      Nice post.

      Perhaps it would be fair to say that JSONP != CORS; they are two different approaches to solving the issue. While JSONP is script tag injection, CORS is about header-based negotiation. I guess I thought this was worth pointing out as "CORS" appears a number of times in your post, including here:

      "http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message=someData"

      which may confuse some readers.

      Also, you can't make "arbitrary" web service calls with JSONP; for example, you can't use the POST method.

      thanks

      dj

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hi DJ,

      You are right and I have edited the article. I tried to convey the Web Origin Access Issue and how to tackle it via JSONP in vanilla javascript as most developers use JQuery and ignore the behind the scene working.

      As rightly stated CORS != JSONP , they are two different solutions for resolving the same issue.

      Thanks for your inputs. 🙂

      Regards,

      Ajain