PHP: How to easily provide JSON and JSONP

Have some server-side data that you would like to grab through an AJAX call? For example by using the jQuery.ajax method?

A really easy way of doing this is by using the JSON format.

JSON

It is hyper simple. All you need to do is to set the content-type to application/json and encode your data using the json_encode function.

<?php header('content-type: application/json; charset=utf-8');

$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);

echo json_encode($data);

You can test it out for example in the FireBug console by running this line:

$.ajax({url: 'data.php'})
// Response: [1,2,3,4,5,6,7,8,9]

You should see the request being done in the console and also in the Net tab. If it didn’t work, you might be subject to the following:

Due to browser security restrictions, most “Ajax” requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, or protocol.

A nice and simple solution to that problem is JSONP.

JSONP

As stated on Wikipedia,

JSONP or “JSON with padding” is a complement to the base JSON data format, a usage pattern that allows a page to request and more meaningfully use JSON from a server other than the primary server.

I’m not sure I get everything about JSONP, but I have used it and I know that it works :P It’s almost just as easy as plain JSON actually, and all that’s needed is to wrap the JSON encoded data in a callback function provided as a GET parameter.

<?php header('content-type: application/json; charset=utf-8');

$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);

echo $_GET['callback']. '('.json_encode($data).')';

You can test it by running

$.ajax({url: 'data.php', dataType:'jsonp'})
// Response: jsonp1277656587731([1,2,3,4,5,6,7,8,9])

This time you won’t see the call in the FireBug console though, but only in the Net tab. That’s because the data is loaded in a script tag instead of through an actual AJAX call. Thankfully jQuery handles all of that though, so you don’t have to worry about it at all. You’ll get the same JSON data in your response handler, ready to be used however you want to :)

What if you’d like to have both options?

JSON and JSONP

Providing both is easy as cake. Just check if the callback parameter is set or not:

<?php header('content-type: application/json; charset=utf-8');

$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
$json = json_encode($data);

echo isset($_GET['callback'])
    ? "{$_GET['callback']}($json)"
    : $json;

That’s all! Please comment if you have any feedback :)

This entry was posted in Software Development and tagged , , , , . Bookmark the permalink.

3 Responses to PHP: How to easily provide JSON and JSONP

  1. Torleif says:

    Added charset to the content-type header, according to an answer to a question I posted about this on StackOverflow. PHP: Is this safe for providing JSONP?

  2. Benjamin says:

    Hi Torleif,

    I have followed your instruction on jsonp. May firebug console still show the ajax request. May I know is there any more step which I have missed? I call url is as below:

    http://test.com/gt_index.php?callback=jsonp1278499812769&_=1278499813551

    Thank you
    Benjamin.

    • Torleif says:

      I’ve messed around a bit, and although I’m not 100% sure why this happens, it seems to happen when loading a resource from the same domain. In this case JSONP isn’t actually needed either, but I have no clue if there is a connection there.

      When I did $.ajax({url: '/data.php', dataType:'jsonp'}), it showed up in the console. But if I did $.ajax({url: 'http://ajax.googleapis.com/ajax/services/search/blogs?v=1.0&q=geekality', dataType:'jsonp'}), then it didn’t. However, in both cases the request does show up in the Net tab. And if you watch closely in the HTML tab, you will see the head tag highlight for a bit when the script tag is added and removed to load the data.

Leave a Reply

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=""> <strike> <strong>