+40 745 232 788

Online Solutions Development Blog   |  

RSS

JSONP Example

posted by ,
Categories: JavaScript
Taggs , , , ,

JSONP is the answer to two quite popular questions among the web developers:

  • how can I make an asynchronous call to an script that is not on my server?
  • how can I “hide” my ajax calls in the javascript console?

What is JSONP?

Short version: it’s an alternative to ajax.

Long version(with example) below:

I guess most of you know what is JSON. If you don’t there is a lot of information out there about it. You could start by reading some of the wikipedia article on json (you will also find some things about jsonp in that article).

JSONP is nothing else but json with padding. This technology is based on a very simple principle: the fact that you can dynamically add new external javascript sources in your website without problem and that a json response is easy to handle with javascript.

So back to the two questions: notice that the first one uses the term “asynchronous” but not the well known “ajax”. That is because jsonp calls are not in fact ajax calls. This thing answers the second question also: the calls that you know that are made but you don’t see them in the javascript console are not ajax calls.

What do you need to do in order to make a jsonp call?

When you need to make the call dynamically insert into your page a new <script> tag. The source should be a service that outputs a json.

What’s the padding? If you just output a json encoded object in your script at the moment you insert it in your page you will have a new object, but nothing will happen with it. So you can add a function that you know it is available in the page that can “read” the output.

Full working example:

HTML/JS:


<script type="text/javascript">// <![CDATA[
			function callTheJsonp()
			{
				// the url of the script where we send the asynchronous call
				var url = "http://localhost/utils/jsonp/ajax.php?callback=parseRequest";
				// create a new script element
				var script = document.createElement('script');
				// set the src attribute to that url
				script.setAttribute('src', url);
				// insert the script in out page
				document.getElementsByTagName('head')[0].appendChild(script);
			}

			// this function should parse responses.. you can do anything you need..
			// you can make it general so it would parse all the responses the page receives based on a response field
			function parseRequest(response)
			{
				try // try to output this to the javascript console
				{
					console.log(response);
				}
				catch(an_exception) // alert for the users that don't have a javascript console
				{
					alert('product id ' + response.item_id + ': quantity = ' + response.quantity + ' & price = ' + response.price);
				}
			}

// ]]></script>

 <span onclick="callTheJsonp()">click here to make the jsonp call</span>

PHP:

<?php
	// get the callback function name
	$callback = '';
	if (isset($_GET['callback']))
	{
		$callback = filter_var($_GET['callback'], FILTER_SANITIZE_STRING);
	}

	// make an array with some random values.. so you would see that the results are fetched each time you call this script
	$array = array(
					'item_id' => rand(1,13),
					'price' => rand(14,17),
					'quantity' => rand(18,30)

	);
	// output this array json encoded.. the callback function being the padding (a function available in the web page)
	echo $callback . '('.json_encode($array).');';

What just happened?

When the user clicks on the span the callTheJsonp function is called. This function will insert into the page a new element and its source will be in fact a php script. (keep in mind: even if I called that file ajax.php, this is not an ajax)

The php will output his response between parseRequest( and ). So when the response arrives the parseRequest function will be called and the parameter will be the result of the script we called.

So now inside the parseRequest function you have an javascript object with everything you need. From here on you can do anything you want, just the way you did with ajax.

Downsides? A few: ajax is safer (that’s why you can’t make ajax calls to external servers) so you must take care what you do with the response or the fact that you can’t use POST as a request method.

You can download a full working example here.

If you have any questions or feedback please feel free to use the form below to add a comment.

If you liked this post
you can buy me a beer

23 Responses to JSONP Example

  1. Thanks!

  2. I don’t understand how jsonp is asynchronous. The injected script is waiting for the response, is it not? That makes it synchronous. I am trying to figure out how to do an asynch call. I want to find or build a js library that will detect whether the requested url is the same as window.location.href or document.URL. If it’s the same, I will do an AJAX call. If different, XSS or JSONP.

    • Hello, Stanley. Thank you for your feedback. To answer your question: the jsonp calls are asynchronous, they don’t have to wait for the response to come. You can download here an example that shows this. If you unpack that archive and run the index.html file you will see that you can make two jsonp calls by clicking on “click here to make the first jsonp call” or “click here to make the second jsonp call”. The calls are made to two different php files. In the first one the execution is delayed for 3 seconds. This way you can see that if you make the first call and immediately the second one the first response comes from the second script (because the first one takes longer to run). I hope this helps but if you have any more questions please feel free to add another comment.

  3. What is the difference between JSONP approach and JSONRequest (http://json.org/JSONRequest.html) approach?

    • Hello, Ruchir.
      Sorry for the delay, I was away for a while.

      About your question: as you can see on that page JSONRequest is just a proposal. This is a quote from the second sentence: “JSONRequest is proposed as a new browser service[…]”. The author only hopes that the browsers will someday add this feature.

      JSONRequest seems to be a good idea but until it will be available we can use jsonp.

  4. Hi thanks….

    Your code saved my day(in fact years…)

    Regards,
    Chirag

  5. $.ajax({
       cache:     'true',
       async:     'false',
       type:      'GET',
       url:       'http://www.some-site.com/some-file.json', // Point to your url
       dataType:  'jsonp',
       timeout:   1750,										//
       complete:  function(){$('#slider1').bxSlider();}	
    });                                                      // Close Ajax Function
    
    • Hello, Bill. Thanks for dropping your piece of code (even if it is without any words). Yes, this is a well known way to achieve a similar thing but if you are suggesting this as an alternative (because I need to guess what you meant) I need to remind you that this is a jquery method and the purpose of this blog post was to show how this system works in pure javascript, independent of any library

  6. The above code gets the link from some other domain.. How it is not affected with Single origin policy?

  7. javascript src element is not affected with Single origin policy??
    Eg: src= ‘http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js’ is possible..

    • Exactly. That is why this system is not affected by these rules, you can always include a script that is not on your server.

      The Single origin policy is enforced by a set of rules set by the browser, it is not technically impossible to run an ajax from a domain to another, but no browser will allow this (a workaround that can be used for testing while you are developing something would be to disable the security settings in chrome by running it with the –disable-web-security option).

      But this is true only for ajax calls. While you are allowed to include jquery from the google cdn you are also allowed to use jsonp calls.

  8. Thanks for this very simple solution,
    I tried it on two domains and it works on firefox but im getting this error “Uncaught SyntaxError: Unexpected token < " on Google Chrome, have you experienced this issue? thanks a lot.

  9. Thank you for sharing your codes. but it only works in IE, not with Chrome.

    • Hello, James

      I assure you that I checked this before uploading the example not only in IE and Chrome but the other popular browsers (FF, Opera, Safari). In fact there is nothing that complicated that could break in some browser, the sample simply injects a new script tag in the page. The only thing that might be similar to what you are saying is the fact that in some versions of browsers the mime type of the request is checked. So if you are getting the error “Resource interpreted as Script but transferred with MIME type text/html” you can fix it just by adding in your php file just before sending any output something like:

      header('Content-type: text/javascript');
      

      Thanks for bringing this up, it might be a good addition to the post but please note that it has noting to do with the system itself but with some rules implemented by some of the browsers.

  10. I have a simple requirement. I have a .html and this page is in server X. Now I want to write some code in this .html page which would check if server Y is up and running or not. I tried using XMLHttpRequest but could not achieve, may be because of cross domain issues. Please help me out. This is very urgent.

    • You problem doesn’t seem that simple as you want to present it especially considering that you did not provide any specific detail about it. The point of this blog post is to present this solution called JSONP not to solve any problem regarding connections between two servers.

      Yes, you can’t make XMLHttpRequest calls because you are connecting to a different server and JSONP could be a solution but this depends on a lot of factors (first of all: does that server generate any type of response that can be used this way?).

      Please comment on blog posts (at least on this site) if you have anything to say directly related to the topic (ask for specific clarifications, make useful additions, report a problem etc). If you want to employ our company’s services feel free to use the contact form to present your problem as detailed as possible and somebody will get back to you with a price offer or followup questions.

Add a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Also, if you want to display source code you can enclose it between [html] and [/html], [js] and [/js], [php] and [/php] etc