Fork me on GitHub

JSON Formats d'échange de données en AJAX

Formats de données en AJAX

AJAX est l’acronyme de « Asynchronous JavaScript and XML ».

Mais chaque composant est optionnel, en particulier XML !

Selon l’application, l’un des formats suivants peut être mieux adapté qu’un autre :

  • Pas de données : les entêtes HTTP suffisent ;
  • Texte simple ;
  • Extraits de HTML ;
  • JavaScript, CSS, … ;
  • JSON, autres formats légers (YAML, …) ;
  • XML, autres formats structurés (XHTML, …) ;
  • Données binaires, encodage Base64, … ;

Utiliser l’entête Content-Type pour déclarer le format.

Texte ou rien

Pour des actions simples comme

  • Sauvegardes automatiques (mails, documents, etc.),
  • Avancement.
POST /api/savemail HTTP/1.1
Host: webmail.example.com
...

Cher Monsieur,

Par la présente je vo
HTTP/1.1 200 OK
Content-Type: text/plain
...

39

HTML

Pour une inclusion directe de fragments HTML (par ex., billets de blog, commentaires, …)

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>J'ai toujours cru...

Exemple d’inclusion dans le document:

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

Problème: Viole la séparation entre données, présentation et logique.

XML

Pour des données riches et structurées (par ex., requêtes BD, geodata, …)

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

(La requête a été légèrement modifiée pour faciliter la lecture)

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

Évaluation, manipulation

  • XPath: Query language pour la sélection de nœuds dans un arbre XML ;
  • XSLT (Extensible Stylesheet Language Transformations): transformations de documents XML.

Avantages / Désavantages

  • Puissant, robuste ;
  • Verbeux, relativement lent ;
  • Peux d’implantations complètes ;
  • Spécification énorme avec des risques de failles de securité.

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' }

Exemple d’inclusion dans le document

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

Problèmes graves

  • Viole la séparation de la logique ;
  • Grande risque de failles XSS.

JSON (JavaScript Object Notation)

JSON est un langage léger de représentation de données, basé sur 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" }

Pour / Contre

  • Plus compact que XML, facile et rapide à évaluer ;
  • Moins puissant que XML ;
  • Supporté par tous les browsers modernes ;
  • Pas de risques d’évaluer du code dangéreux ;
  • Peut créer une vulnérabilité XSS si évalué avec eval().

JSON

Types de données

  • Nombres : 10, 10.3, 10.0003e-10,
  • Chaînes de caractères : "abcdef",
  • Booléens : true, false,
  • null,
  • Listes : [ 1, 2, "abcdef", true ],
  • Objects : { "clef" : "valeur", "autre_clef" : 1, "encore_une" : null }.

Exemple JSON

{
  "voitures" :
  [
    { "modèle"          : "peugeot",
	  "couleur"         : "bleu",
	  "immatriculation" : 2008,
	  "révisions"       : [ 2012, 2014 ]
    },
	{ "modèle"          : "citroën",
	  "couleur"         : "blanc",
	  "immatriculation" : 1999,
	  "révisions"       : [ 2003, 2005, 2007, 2009, 2011, 2013 ]
	}
  ],
  "date" : "2015-03-18"
}

JavaScript ⊄ JSON

{ "voiture"  : "peugeot",
  "vitesses" : [1, 2, 3, 10] }

Codes JavaScript équivalents qui donnent une erreur en JSON :

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

Utilisation de JSON

Silex : Transformer un objet PHP en réponse JSON

return $app->json(array( "voiture" => "peugeot",
                         "vitesses" => array(1, 2, 3, 10)));

Express : Transformer un objet JavaScript en réponse JSON

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

Browser/Node.js : Transformations JSON ↔ Objet JavaScript

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 : interprétation automatique des réponses JSON

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

Lectures

Quelques consoles pour tester des APIs JSON