JavaScript/Handling JSON

From Wikibooks, open books for an open world
Jump to navigation Jump to search



Native JSON[edit | edit source]

Modern JSON Handling[edit | edit source]

Handling JSON may require adding a supporting library, which creates the global JSON object. This object is present natively only in new browsers (e.g. FF 3.5, IE8). Such a library can be found here:

//Parsing JSON:
var myObject = JSON.parse(myJSONtext)

//Creating JSON:
var myJSONText = JSON.stringify(myObject);

Old way[edit | edit source]

In old browsers you could use the following syntax, but this raises issues of security, such as XSS.

var myObject = eval("(" + myJSONtext + ")")

JSONP[edit | edit source]

Given browser restrictions on cross-domain Ajax (allowed only by configuration in some earlier browsers, by non-standard means in IE8, and with server headers in HTML5), one way to circumvent such restrictions (while still requiring some server-side script coordination) is for sites to insert an HTML script tag dynamically into their code, whereby the cross-domain script they target (typically) supplies JSON, but wrapped inside a function call (the function name being supplied according to the value of a "callback" parameter supplied by the requestor) or some other executable code.

In PHP, one might serve such JSONP in as simple a fashion as this:

<?php
if (isset($_GET['callback'])) {
  header('Content-Type: application/javascript');
  $our_site_data = ... // Set to an array or object containing data to be supplied for use at other sites
  print $_GET['callback'] . '(' . json_encode($our_site_data) . ')';
}
?>

jQuery and other frameworks have their own means of generating JSONP requests, but we'll use the following custom code.

Note: It is important to bear in mind that the following code should not be used, if the targeted site or the data supplied by the target site, may come from a non-trustworthy source, since it is possible for such scripts to run with the privileges of the using site (e.g., to read user cookies and pass them on to another site) and thereby execute a Cross-site scripting attack.

<script>
var JSONP = function(global) { // Introduces only one global
  // MIT Style license, adapted from http://devpro.it/code/209.html
  function JSONP(uri, callback) {
    function JSONPResponse() {
      // Reduce memory by deleting callbacks when finished
      try { delete JSONP[src] } catch(e) { JSONP[src] = null; }
      documentElement.removeChild(script);
      // Execute the user's callback with the arguments supplied by the server's JSONP call
      if (typeof callback === 'string') { // Assumes only one return argument and that it is an HTML string
        document.getElementById(callback).innerHTML = arguments[0];
      } else {
        callback.apply(this, arguments);
      }
    }
    // Ensure a unique callback
    var src = '_' + id++,
    script = document.createElement("script");
    // Add our callback as a property of this JSONP
    // function to avoid introducing more globals
    JSONP[src] = JSONPResponse;
    // We include "callback", as it is typically used in
    // JSONP (e.g., on Wikibooks' API) to specify the callback
    documentElement.insertBefore(
      script,
      documentElement.lastChild
    ).src = uri + (uri.indexOf('?') === -1 ? '?' : '&') + "callback=JSONP." + src;
  }
  var id = 0, documentElement = document.documentElement;
  return JSONP;
}(this);

// Get the parsed HTML of this page you are reading now
// using the Mediawiki API (See http://en.wikibooks.org/w/api.php
// for Wikibooks, but it also applies at other Mediawiki wikis) that
// allows for such cross-domain calls
JSONP('http://en.wikibooks.org/w/api.php?action=parse&format=json&page=JavaScript/Handling_JSON',
  function (data) {
    alert(data.parse.text['*']);
  }
);
</script>

More information[edit | edit source]