Tu colles ce qui ressemble à des données valides dans un parser JSON et il lance immédiatement SyntaxError: Unexpected token '''. Les données viennent de ton code source JavaScript et paraissent complètement raisonnables —— mais JSON et les object literals JavaScript ne sont pas le même format, et les différences comptent bien plus que la plupart des développeurs ne le réalisent.
La réponse courte : JSON ne supporte pas les apostrophes
Les apostrophes sont carrément illégales en JSON. Chaque chaîne —— clés comme valeurs —— doit utiliser des guillemets doubles. Pas d'exception.
// ❌ JSON invalide —— chaînes en apostrophes
{ 'name': 'Ada Lovelace', 'active': true }
// ✅ JSON valide
{ "name": "Ada Lovelace", "active": true }L'erreur que tu verras dans différents environnements :
// Chrome / Node.js (V8)
SyntaxError: Unexpected token "'", "{'name':..." is not valid JSON
// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data
// Safari
SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSONLe message de Safari est le plus utile —— il te dit exactement quel est le problème. Les autres signalent juste le caractère inattendu.
Pourquoi JSON exige-t-il des guillemets doubles ?
JSON a été défini par Douglas Crockford en 2001 et standardisé comme RFC 8259. La grammaire spécifie exactement un délimiteur de chaîne : le caractère guillemet double (U+0022). Les apostrophes ne sont tout simplement pas dans la grammaire.
La raison est la simplicité. JSON est un format d'échange de données pensé pour être parsé par n'importe quel langage, pas seulement JavaScript. En imposant un seul style de quoting, la spec élimine toute une classe d'ambiguïté. Les parsers en Go, Python, Java, Rust et tout autre langage implémentent exactement la même règle.
JSON vs object literal JavaScript : les différences complètes
Les apostrophes ne sont qu'une de plusieurs différences. Voici le tableau complet :
1. Les clés doivent être des chaînes entre guillemets doubles
// ❌ Object literal JavaScript —— clé nue, clé en apostrophes
{ name: "Ada", 'score': 98 }
// ✅ JSON —— toutes les clés sont des chaînes entre guillemets doubles
{ "name": "Ada", "score": 98 }Les object literals JavaScript acceptent les identifiants nus, les chaînes en apostrophes et les chaînes en guillemets doubles comme clés. JSON n'accepte que les chaînes en guillemets doubles.
2. Pas de virgules finales
// ❌ JSON invalide
{ "name": "Ada", "score": 98, }
// ^ virgule finale
// ✅ JSON valide
{ "name": "Ada", "score": 98 }JavaScript moderne autorise explicitement les virgules finales. JSON non — — voir notre guide complet sur les virgules finales en JSON.
3. Pas de commentaires
// ❌ JSON invalide
{
// profil utilisateur
"name": "Ada"
}
// ✅ JSON n'a pas de syntaxe de commentaires
{ "name": "Ada" }JSON n'a aucune syntaxe de commentaires. Si tu as besoin de commentaires dans des fichiers de config, considère le format JSONC (JSON-with-Comments), supporté par les réglages VS Code, le tsconfig.json de TypeScript et plusieurs parsers de fichiers de config.
4. Pas de undefined, fonctions ou symbols
// Objet JavaScript —— accepte les valeurs non sérialisables
const obj = {
fn: () => 42, // fonction
sym: Symbol('id'), // Symbol
val: undefined, // undefined
};
// JSON.stringify les drop ou convertit silencieusement
JSON.stringify(obj);
// → '{}' (les trois propriétés disparaissent ou deviennent null) JSON supporte exactement six types de valeur : string, number, boolean (true/false), null, object et array. Fonctions, Symbols et undefined n'ont pas de représentation JSON. JSON.stringify() drop silencieusement les propriétés d'objet avec ces valeurs et les convertit en null dans les arrays.
5. Pas de NaN ni Infinity
JSON.stringify({ ratio: NaN, limit: Infinity });
// → '{"ratio":null,"limit":null}'
// NaN et Infinity deviennent null —— silencieusement !
JSON.parse('{"ratio": NaN}');
// → SyntaxError: Unexpected token 'N'NaN et Infinity sont des valeurs numériques JavaScript valides mais ne font pas partie de la spécification de nombre JSON. JSON.stringify() les convertit en null en sortie ; JSON.parse() les rejette en entrée. Cette asymétrie est une source courante de bugs subtils.
6. Nombres : pas d'hex, pas de zéros en tête, pas de +
// ❌ JSON invalide
{ "flags": 0xFF, "code": 007, "delta": +1.5 }
// ✅ JSON valide
{ "flags": 255, "code": 7, "delta": 1.5 } Les nombres JSON doivent être décimaux, ne peuvent pas commencer par un signe + explicite, et ne peuvent pas avoir de zéros en tête (sauf le chiffre unique 0 avant un point décimal). Les littéraux hexadécimaux et octaux ne sont pas du JSON valide.
7. Pas de chaînes multi-lignes
// ❌ JSON invalide —— saut de ligne littéral dans la chaîne
{ "bio": "Line one
Line two" }
// ✅ Utilise la séquence d'échappement
{ "bio": "Line one\nLine two" }8. Clés calculées, clés Symbol et shorthand de méthode
Trois autres features uniquement JS qui ressemblent à du JSON mais n'ont aucun équivalent :
// ❌ Noms de propriété calculés —— évalués, pas littéraux
const k = "id";
const obj = { [k]: 1, [`user_${k}`]: 1 };
// JSON n'a pas d'expressions ; la clé doit être une chaîne littérale entre guillemets doubles.
// ❌ Clés Symbol —— droppées silencieusement par JSON.stringify
const tag = Symbol('tag');
JSON.stringify({ [tag]: 'admin' }); // → '{}'
// ❌ Shorthand de méthode —— les fonctions sont droppées/omises
const obj = { greet() { return 'hi'; } };
JSON.stringify(obj); // → '{}' Si tu as besoin d'une de ces choses, sérialise une projection en forme de JSON de ton objet —— JSON.stringify() ne produit jamais que des clés en string et les six types de valeur JSON.
Une cheatsheet rapide de conversion
| Object literal JavaScript | Équivalent JSON valide |
|---|---|
{ name: "Ada" } | {"name":"Ada"} |
{ 'name': 'Ada' } | {"name":"Ada"} |
{ a: 1, } | {"a":1} |
{ val: undefined } | {} (propriété droppée) |
{ n: NaN } | {"n":null} |
{ n: Infinity } | {"n":null} |
{ fn: () => 1 } | {} (propriété droppée) |
0xFF | 255 |
La façon la plus sûre de convertir un objet JS en JSON
N'essaie jamais de convertir un objet JavaScript en JSON en éditant les guillemets à la main. Utilise JSON.stringify() —— il gère correctement chaque cas limite :
const obj = { name: 'Ada', score: 98, active: true };
// Compact
JSON.stringify(obj);
// → '{"name":"Ada","score":98,"active":true}'
// Pretty-print avec indent à 2 espaces
JSON.stringify(obj, null, 2);
// → '{
"name": "Ada",
"score": 98,
"active": true
}' Le deuxième argument de JSON.stringify() est un replacer —— tu peux passer un tableau de noms de clé pour n'inclure que ces propriétés, ou une fonction pour transformer les valeurs :
// N'inclure que des clés spécifiques
JSON.stringify(obj, ['name', 'score'], 2);
// → '{
"name": "Ada",
"score": 98
}'
// Replacer custom —— convertir undefined en null
JSON.stringify({ a: 1, b: undefined }, (key, value) =>
value === undefined ? null : value
);
// → '{"a":1,"b":null}'Quand tu reçois un object literal JS sous forme de chaîne
Parfois tu reçois des données qui ressemblent à du JSON mais sont en fait un object literal JavaScript —— peut-être d'un fichier de log, d'un outil de debug, ou d'une API qui ne respectait pas la spec. Dans ce cas JSON.parse() échouera et tu as deux options :
- Utiliser un parser de réparation —— convertit les apostrophes en guillemets doubles, retire les virgules finales, met entre guillemets les clés nues, et gère automatiquement toutes les autres différences. C'est l'approche la plus sûre pour de l'input non fiable.
- Utiliser
eval()ouFunction()—— marche techniquement pour du JavaScript valide, mais c'est un risque de sécurité sérieux si la source n'est pas pleinement fiable. Ne fais jamais ça avec de l'input fourni par les utilisateurs.
Foire aux questions
Est-ce que JSON supporte les apostrophes ?
Non. La grammaire JSON (RFC 8259) définit exactement un délimiteur de chaîne —— le guillemet double. Clés comme valeurs doivent utiliser des guillemets doubles ; les apostrophes lancent un SyntaxError.
Quelle est la différence entre JSON et un objet JavaScript ?
JSON est un format texte strict ; un object literal JavaScript est du code permissif. JS permet les apostrophes, les clés sans guillemets, les virgules finales, les commentaires, undefined, NaN, les fonctions et les nombres hex —— aucun n'est du JSON valide. Voir la cheatsheet complète plus haut et l'introduction à Qu'est-ce que JSON ?
Comment convertir un objet JavaScript en JSON ?
Utilise JSON.stringify() —— n'édite jamais les guillemets à la main. Il gère tout cas limite, drop les valeurs non sérialisables et échappe correctement les chaînes.
Pourquoi ne puis-je pas utiliser eval() pour parser un object literal JS ?
eval() exécute du code arbitraire, donc c'est un risque de sécurité sérieux sur de l'input non fiable. Utilise un parser de réparation (ou JSON Fix) pour convertir un object literal JS en JSON valide de manière sûre.
Répare les apostrophes instantanément
Si tu as un object literal JavaScript que tu dois convertir en JSON valide tout de suite, JSON Fix gère la conversion automatiquement. Il convertit les apostrophes en guillemets doubles, met entre guillemets les clés nues, retire les virgules finales et corrige toutes les autres différences listées plus haut —— dans ton navigateur, sans données envoyées vers un serveur.
- JSON Fix —— convertis instantanément des object literals JS en JSON valide
- Corriger les apostrophes en JSON —— guide de référence rapide avec exemples cassés et corrigés
- JSON vs Object Literal JavaScript —— chaque différence de syntaxe avec exemples côte à côte
- Erreurs Unexpected Token de JSON.parse —— un guide pour chaque variante du SyntaxError que tu peux voir
- Virgules finales en JSON —— pourquoi elles sont permises en JS mais interdites en JSON