JSON Data formats and AJAX

AJAX and data formats

AJAX stands for “Asynchronous JavaScript and XML”.

But every component is optional, XML above all!

Depending on the application, one of the following data formats may be preferred:

  • No data: HTTP headers are enough;
  • Simple text;
  • HTML excerpts;
  • JavaScript, CSS, …;
  • JSON, other lightweight formats (YAML, …);
  • XML, other structured formats (XHTML, …);
  • Binairy data, Base64 encoded data, …;

Use the Content-Type HTTP header to declare the format.

Text or nothing

For simple actions, such as

  • Auto-saves (mails, documents, etc.),
  • Progress.
POST /api/savemail HTTP/1.1
Host: webmail.example.com
...

Dear Sir,

I am wrting to y
HTTP/1.1 200 OK
Content-Type: text/plain
...

39

HTML

For direct inclusion of HTML fragments (e.g., blog posts, comments, …)

GET /api/post/23389 HTTP/1.1
Host: blog.example.com
...
HTTP/1.1 200 OK
Content-Type: text/html
...

<article class='post' id='post23389'><p>I've always believed...

Example: attaching to the DOM

xhr.onload = function() {
    $('#main').innerHTML = xhr.responseText;
});

Problem: Violates separation betwen data, presentation and logic.

XML

For rich, structured data (e.g., DB requests, geodata, …)

GET /v1/public/yql?q=SELECT * FROM geo.places WHERE text="Paris" HTTP/1.1
Host: query.yahooapis.com
...

(the request has been slightly modified to ease reading)

HTTP/1.1 200 OK
Content-Type: application/xml
...

<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="10" yahoo:created="2015-03-17T22:05:40Z" yahoo:lang="en-US">
    <results>
        <place xmlns="http://where.yahooapis.com/v1/schema.rng" xml:lang="en-US" yahoo:uri="http://where.yahooapis.com/v1/place/615702">
            <woeid>615702</woeid>
            <placeTypeName code="7">Town</placeTypeName>
            <name>Paris</name>
            ...

XML

Evaluation, manipulation

  • XPath: Query language for selecting nodes in a XML tree;
  • XSLT (Extensible Stylesheet Language Transformations): XML document transformations.

Advantages / Disadvantages

  • Powerful, robust;
  • Verbose, relatively slow;
  • Few complete implementations;
  • Huge specification, with security risks.

JavaScript

GET /api/car?user=toto HTTP/1.1
Host: www.example.com
...
HTTP/1.1 200 OK
Content-Type: application/javascript
...

{ car : 'peugeot', color : 'blue' }

Example: attaching to the DOM

xhr.onload = function() {
  var res = eval(xhr.responseText);
}

Serious problems

  • Violates separation from logic;
  • Huge XSS risk!

JSON (JavaScript Object Notation)

JSON is a lightweight data representation language, based on JavaScript.

GET /api/car?user=toto HTTP/1.1
Host: www.example.com
...
HTTP/1.1 200 OK
Content-Type: application/json
...

{ "car" : "peugeot", "color" : "blue" }

Pros / Cons

  • More compact than XML, easy and fast to evaluate;
  • Less powerful than XML;
  • Supported by all modern browsers;
  • No security risks…
  • …unless you evaluate it with eval(), of course.

JSON

Data types

  • Numbers: 10, 10.3, 10.0003e-10,
  • Strings: "abcdef",
  • Booleans: true, false,
  • null,
  • Lists: [ 1, 2, "abcdef", true ],
  • Objects: { "key" : "value", "other_key" : 1, "one_more" : null }.

JSON example

{
  "cars" :
  [
    { "model"       : "peugeot",
      "color"       : "blue",
      "plate"       : 2008,
      "inspections" : [ 2012, 2014 ]
    },
    { "model"       : "citroën",
      "color"       : "white",
      "plate"       : 1999,
      "inspections" : [ 2003, 2005, 2007, 2009, 2011, 2013 ]
    }
  ],
  "date" : "2015-03-18"
}

JavaScript ⊄ JSON

{ "car"   : "peugeot",
  "gears" : [1, 2, 3, 10] }

Some equivalent JavaScript code that is invalid JSON:

{ 'car'   : 'peugeot',
  'gears' : [1, 2, 3, 10] }
{ car   : "peugeot",
  gears : [1, 2, 3, 10] }
{ "car"   : "peugeot",
  "gears" : [1, 2, 3, 10, ], }
{ "car"   : "peugeot",
  "gears" : [0x1, 0x2, 0x3, 0xA] }

Using JSON

Express: Transform a JavaScript object in JSON response

res.json({ car: "peugeot",
           gears: [1, 2, 3, 10] });

Browser/Node.js: Transform JSON ↔ JavaScript object

var a = JSON.stringify({ a: "b",
                         c: [1, 2] });
console.log(a);
console.log(JSON.parse(a));
{"a":"b","c":[1,2]}
Object { a: "b", c: [1, 2] }

AJAX: automatic interpretation of JSON responses

xhr.responseType = 'json';
xhr.onload = function() {
  console.log(xhr.response);
}
Object { car: "peugeot",
         gears : [1, 2, 3, 10] }

References

Some JSON API consoles for testing

Fork me on GitHub