Tutoriel JSON : syntaxe, règles et utilisation en JavaScript et en Python
JSON est le format d'échange de données le plus simple et le plus répandu : avec quelques règles courtes et deux fonctions par langage, vous pouvez lire, créer et stocker n'importe quelles données.
Si vous travaillez avec des API, des applications mobiles ou même le fichier de configuration d'un projet, vous croiserez tôt ou tard du JSON. JSON est un format texte qui sert à stocker et à transporter des données, lisible par les humains et facile à traiter pour tous les langages de programmation. Ce tutoriel commence par la définition et les règles de syntaxe, décortique un exemple réel, passe ensuite à la lecture et à l'écriture de JSON en JavaScript et en Python, avec une attention particulière aux lettres accentuées et aux autres textes non anglais, et termine par les erreurs courantes et la façon de les repérer avec le formateur JSON. Tout le code de cette page a été exécuté, et les résultats affichés sont réels.
Qu'est-ce que JSON ?
JSON signifie JavaScript Object Notation. Sa syntaxe vient de la façon dont on écrit les objets en JavaScript, mais il n'est lié à aucun langage : Python, PHP, Java, C#, Go et pratiquement tous les autres langages disposent d'outils prêts à l'emploi pour le manipuler. JSON est défini par les normes RFC 8259 et ECMA-404, ses fichiers portent l'extension .json et son type de média sur le web est application/json. Usages courants :
- API web : la plupart des services modernes envoient leurs requêtes et leurs réponses en JSON.
- Fichiers de configuration : comme
package.jsondans les projets Node.js oucomposer.jsonen PHP. - Stockage de données : dans le
localStoragedu navigateur, dans les colonnes JSON de bases de données comme PostgreSQL et MySQL, et dans les bases de données orientées documents.
Les règles de syntaxe JSON
Tout document JSON est construit à partir de six types de valeurs, qui peuvent être imbriqués les uns dans les autres :
| Type | Exemple | Description |
|---|---|---|
| object | {"city": "Lisbon"} | Des paires clé-valeur entre accolades |
| array | [1, 2, 3] | Une liste ordonnée de valeurs entre crochets |
| string | "hello" | Du texte entre guillemets doubles |
| number | 42, -3.5, 1.2e6 | Entier ou décimal, sans guillemets |
| boolean | true, false | Uniquement en minuscules |
| null | null | L'absence de valeur |
Les règles à l'origine de la plupart des erreurs :
- Les clés sont toujours des chaînes entre guillemets doubles :
{"name": "Ali"}est correct,{name: "Ali"}ne l'est pas. - Seuls les guillemets doubles sont autorisés ;
'Ali'entre guillemets simples n'est pas du JSON valide. - Les virgules finales sont interdites : aucune virgule ne doit suivre le dernier membre d'un objet ou d'un tableau.
- Il n'y a pas de commentaires : ni
//ni/* */. - Les valeurs propres à un langage sont interdites :
undefined,NaN,Infinity,TrueetNonene sont pas du JSON valide. - Un nombre ne peut pas commencer par un zéro :
012est invalide. C'est pourquoi les numéros de téléphone, les codes postaux et les identifiants du même genre doivent être écrits sous forme de chaînes, comme"0123456789"; le zéro initial est ainsi conservé. - Les caractères spéciaux des chaînes sont échappés :
\"pour un guillemet double,\\pour une barre oblique inverse,\npour un saut de ligne et\uXXXXpour n'importe quel caractère Unicode. - Les espaces et les sauts de ligne entre les éléments n'ont pas d'importance ; c'est pourquoi le JSON peut s'écrire aussi bien de façon compacte sur une seule ligne que proprement indenté.
Un exemple réel : une commande de boutique en ligne
{
"orderId": 10245,
"createdAt": "2026-09-17T10:30:00Z",
"customer": {
"name": "Maria",
"phone": "0123456789",
"city": "Lisbon"
},
"items": [
{ "title": "Python for Beginners", "price": 32, "qty": 1 },
{ "title": "Wireless Mouse", "price": 45, "qty": 2 }
],
"paid": true,
"discountCode": null
}
Cet exemple réunit tous les types de valeurs. customer est un objet imbriqué et items un tableau d'objets. Les prix sont des nombres, mais le numéro de téléphone est une chaîne afin de conserver son zéro initial. JSON n'a pas de type « date » : l'heure de la commande est donc une chaîne au format standard ISO 8601. Enfin, discountCode utilise null pour indiquer que cette commande n'avait pas de code de réduction. Pour lire le prix du deuxième article, on écrit order.items[1].price en JavaScript et order["items"][1]["price"] en Python.
Manipuler du JSON en JavaScript
JavaScript dispose de deux fonctions intégrées qui suffisent pour la plupart des tâches : JSON.parse transforme un texte JSON en objet, et JSON.stringify transforme un objet en texte JSON.
Lire du JSON avec JSON.parse
const text = '{"name": "Maria", "age": 28, "skills": ["JavaScript", "Python"], "active": true}';
const user = JSON.parse(text);
console.log(user.name); // Maria
console.log(user.skills[0]); // JavaScript
console.log(user.active); // true
Créer du JSON avec JSON.stringify
const product = { title: "Café Guide", price: 32, tags: ["travel", "bestseller"], discount: null };
console.log(JSON.stringify(product));
console.log(JSON.stringify(product, null, 2));
Le premier appel produit un JSON compact sur une seule ligne, adapté à l'envoi sur le réseau ; le second, avec 2 comme troisième argument, produit une sortie lisible, indentée de deux espaces. Le deuxième argument sert à filtrer ou à transformer les valeurs et reste généralement à null. Le résultat :
{"title":"Café Guide","price":32,"tags":["travel","bestseller"],"discount":null}
{
"title": "Café Guide",
"price": 32,
"tags": [
"travel",
"bestseller"
],
"discount": null
}
Les lettres accentuées et les autres textes non ASCII restent exactement tels quels dans la sortie de JSON.stringify ; ils ne sont pas convertis en séquences \u.
Récupérer du JSON depuis une API et l'enregistrer dans localStorage
async function loadProduct() {
const res = await fetch("https://api.example.com/products/1");
return await res.json();
}
localStorage.setItem("cart", JSON.stringify({ items: [101, 205] }));
const cart = JSON.parse(localStorage.getItem("cart"));
console.log(cart.items.length); // 2
La méthode res.json() analyse elle-même la réponse et renvoie un objet : ne repassez pas son résultat à JSON.parse. localStorage ne stocke que des chaînes : l'objet est donc converti avec JSON.stringify à l'enregistrement et avec JSON.parse à la lecture.
Les valeurs que JSON.stringify modifie
const data = { a: undefined, b: () => 1, c: NaN, d: new Date(Date.UTC(2026, 8, 17)) };
console.log(JSON.stringify(data));
// {"c":null,"d":"2026-09-17T00:00:00.000Z"}
Les clés dont la valeur est undefined ou une fonction disparaissent sans avertissement, NaN et Infinity deviennent null, et une date devient une chaîne ISO. Quand vous analysez à nouveau le résultat, la date reste une chaîne et ne redevient pas d'elle-même un objet Date.
Gérer les erreurs
try {
JSON.parse("{'name': 'Ali'}");
} catch (err) {
console.log(err.name); // SyntaxError
console.log(err.message); // Expected property name or '}' in JSON at position 1 (line 1 column 2)
}
Tout texte invalide déclenche une SyntaxError : traitez donc les données venues de l'extérieur dans un bloc try...catch. Le message ci-dessus est celui de Node.js, identique à celui de Chrome ; Firefox et Safari signalent la même erreur avec d'autres mots.
Manipuler du JSON en Python
En Python, le module standard json fait tout le travail, et il n'y a rien à installer. Il propose quatre fonctions principales : json.loads et json.dumps travaillent sur des chaînes, tandis que json.load et json.dump travaillent directement sur des fichiers ; le s des deux premières signifie string (chaîne).
Transformer une chaîne JSON en dictionnaire
import json
text = '{"name": "Maria", "age": 28, "skills": ["JavaScript", "Python"], "active": true}'
user = json.loads(text)
print(user["name"]) # Maria
print(type(user)) # <class 'dict'>
print(user["active"]) # True
| JSON | Python | JavaScript |
|---|---|---|
| object | dict | Object |
| array | list | Array |
| string | str | String |
| number | int ou float | Number |
true / false | True / False | true / false |
null | None | null |
Convertir des données en JSON, et le problème des textes non ASCII
product = {"title": "Café Guide", "price": 32, "tags": ["travel", "bestseller"], "discount": None}
print(json.dumps(product))
print(json.dumps(product, ensure_ascii=False, indent=2))
La première ligne de sortie risque de vous surprendre :
{"title": "Caf\u00e9 Guide", "price": 32, "tags": ["travel", "bestseller"], "discount": null}
Par défaut, json.dumps écrit chaque caractère non ASCII sous la forme \uXXXX : é devient \u00e9, et un texte dans n'importe quelle autre écriture est échappé caractère par caractère de la même manière. Cette sortie est valide et tous les programmes la lisent correctement, mais elle est illisible pour un humain et prend plus de place. Avec ensure_ascii=False, le texte est écrit tel quel, et indent=2 met en forme la sortie exactement comme dans l'exemple JavaScript.
Lire et écrire des fichiers JSON
with open("product.json", "w", encoding="utf-8") as f:
json.dump(product, f, ensure_ascii=False, indent=2)
with open("product.json", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded["tags"][0]) # travel
Deux points importants : passez aussi ensure_ascii=False à json.dump, et ouvrez toujours le fichier avec encoding="utf-8". Sous Windows, si vous ne précisez pas l'encodage, Python peut se rabattre sur l'encodage par défaut du système, qui n'est pas UTF-8 : vous obtenez alors soit une UnicodeEncodeError, soit un fichier rempli de caractères illisibles.
La sortie de print n'est pas du JSON
print(product)
# {'title': 'Café Guide', 'price': 32, 'tags': ['travel', 'bestseller'], 'discount': None}
Une erreur très fréquente consiste à coller quelque part, en guise de JSON, la sortie de print d'un dictionnaire. Ce texte est la représentation propre à Python : il contient des guillemets simples et None au lieu de null, si bien qu'aucun analyseur JSON ne l'acceptera. Pour produire du JSON, utilisez toujours json.dumps.
Gérer les erreurs en Python
try:
json.loads("{'name': 'Ali'}")
except json.JSONDecodeError as e:
print(e) # Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
json.JSONDecodeError est une sous-classe de ValueError, et ses attributs lineno, colno et pos donnent la position de l'erreur. Si vous utilisez la bibliothèque requests, response.json() effectue la même conversion pour une réponse d'API. Une différence subtile : par défaut, Python accepte NaN en entrée et l'écrit aussi en sortie, alors que cette valeur n'appartient pas au JSON standard ; pour l'éviter, passez allow_nan=False à json.dumps.
Les erreurs JSON courantes et le sens des messages
| Erreur | Exemple invalide | Message JavaScript (Node.js et Chrome) | Message Python |
|---|---|---|---|
| Guillemets simples ou clé sans guillemets | {'name': 'Ali'} | Expected property name or '}' | Expecting property name enclosed in double quotes |
| Virgule finale dans un objet | {"a": 1,} | Expected double-quoted property name | Python 3.14 : Illegal trailing comma before end of object ; Python 3.12 : Expecting property name enclosed in double quotes |
| Virgule finale dans un tableau | [1, 2,] | Unexpected token ']' | Python 3.14 : Illegal trailing comma before end of array ; Python 3.12 : Expecting value |
| Virgule manquante, ou commentaire après une valeur | {"a": 1 "b": 2} | Expected ',' or '}' after property value | Expecting ',' delimiter |
| Une valeur Python ou JavaScript | {"a": True} | Unexpected token 'T' | Expecting value |
| Un nombre commençant par zéro | {"phone": 0123456789} | Unexpected number | Expecting ',' delimiter |
| Chaîne non terminée | {"a": "x} | Unterminated string | Unterminated string starting at |
| Entrée vide | Texte vide | Unexpected end of JSON input | Expecting value |
Les messages indiquent généralement aussi la position, comme position 8 ou line 1 column 9, et le vrai problème se trouve souvent juste avant cet endroit. Si un message JavaScript commence par Unexpected token '<', vous avez probablement reçu une page HTML au lieu de JSON, par exemple une page d'erreur 404 ou une page de connexion ; le guide consacré à l'erreur Unexpected token détaille ce cas. Un fichier enregistré avec un BOM provoque l'erreur Unexpected UTF-8 BOM en Python ; ouvrez-le avec encoding="utf-8-sig" ou enregistrez-le sans BOM.
Formater et valider avec le formateur JSON
Quand un long document JSON arrive sur une seule ligne, ou que vous ne comprenez pas pourquoi il refuse d'être analysé, le formateur JSON est le moyen le plus rapide d'avancer. L'outil s'appuie sur l'analyseur JSON du navigateur lui-même, et les données ne quittent jamais votre navigateur : vous pouvez donc examiner sans risque des réponses d'API qui contiennent des jetons ou des données utilisateur. Les étapes :
- Collez le JSON dans le champ JSON d'entrée ; il est formaté immédiatement, et le bouton Formater fait la même chose.
- Choisissez l'indentation dans le menu Indentation : 2 espaces, 4 espaces ou Tabulation.
- Si le JSON est invalide, un message commençant par
JSON non valide :affiche le texte d'erreur du navigateur, qui indique généralement la position du problème ; servez-vous du tableau ci-dessus pour comprendre ce qu'il signifie et le corriger. - L'onglet Arbre affiche les données sous forme d'arborescence repliable, et Tout déplier et Tout replier ouvrent ou ferment toutes les branches ; très pratique pour retrouver une clé dans une réponse volumineuse.
- Pour envoyer ou stocker les données sous forme compacte, Minifier supprime tous les espaces et sauts de ligne. Copiez le résultat avec Copier.
Quand votre code a besoin de types pour le JSON qu'il reçoit, JSON vers types génère des définitions TypeScript, Go ou Python à partir d'un échantillon ; le guide pour typer une réponse d'API en TypeScript détaille la démarche.