Quel est le JSON minimum valide?

175

J'ai lu attentivement la description JSON http://json.org/ mais je ne suis pas sûr de connaître la réponse à la question simple. Quelles chaînes sont le minimum JSON valide possible?

  • "string" la chaîne est-elle valide JSON?
  • 42 le nombre simple est-il JSON valide?
  • true la valeur booléenne est-elle un JSON valide?
  • {} l'objet vide est-il un JSON valide?
  • [] le tableau vide est-il un JSON valide?
Bessarabov
la source
12
Test sur jsonlint.com , les deux derniers sont valides, les autres ne le sont pas.
ironcito
1
certains analyseurs JSON attendent un tableau ou un objet. Ils se plaignent juste d'un nombre ou d'une chaîne.
akonsu
3
À partir de maintenant, ceux-ci sont valides
Brian Colavito
réponse courte - {}
Tukaram Bhosale

Réponses:

157

Au moment de la rédaction de cet article, JSON était uniquement décrit dans la RFC4627 . Il décrit (au début de «2») un texte JSON comme étant un objet ou un tableau sérialisé.

Cela signifie que seules {} et []sont valides, des chaînes JSON complètes dans des analyseurs et des stringifiers qui adhèrent à cette norme.

Cependant , l'introduction de l'ECMA-404 change cela, et les conseils mis à jour peuvent être lus ici . J'ai également écrit un article de blog sur la question.


Cependant, pour compliquer davantage les choses, l' JSONobjet (par exemple JSON.parse()et JSON.stringify()) disponible dans les navigateurs Web est normalisé dans ES5 , et cela définit clairement les textes JSON acceptables comme suit:

Le format d'échange JSON utilisé dans cette spécification est exactement celui décrit par RFC 4627 à deux exceptions près:

  • La production JSONText de niveau supérieur de la grammaire JSON ECMAScript peut consister en n'importe quelle valeur JSONValue plutôt que d'être limitée à un JSONObject ou un JSONArray comme spécifié par la RFC 4627.

  • coupé

Cela signifierait que toutes les valeurs JSON (y compris les chaînes, les valeurs nulles et les nombres) sont acceptées par l'objet JSON, même si l'objet JSON adhère techniquement à la RFC 4627.

Notez que vous pouvez donc stringifier un nombre dans un navigateur conforme via JSON.stringify(5), qui serait rejeté par un autre analyseur qui adhère à RFC4627, mais qui n'a pas l'exception spécifique répertoriée ci-dessus. Ruby, par exemple, semble être un exemple qui n'accepte des objets et des tableaux comme la racine . PHP, d'autre part, ajoute spécifiquement l'exception selon laquelle "il codera et décodera également les types scalaires et NULL".

Mat
la source
@amdorra: Pouvez-vous être plus précis où vous voyez cela?
Matt
5
JSON n'est pas un nom, donc "un JSON" n'a pas de sens. Toute "valeur JSON" est une "valeur JSON", mais les analyseurs attendent souvent un "texte JSON" tel que défini dans cette RFC.
IMSoP
2
mon mauvais je vais supprimer ma réponse alors
amdorra
1
@jmoreno Pourriez-vous clarifier votre commentaire? Êtes-vous en train de dire true, falseou nullseul est un texte JSON valide? Pourriez-vous s'il vous plaît citer une source, car cela contredit la plupart des autres réponses / commentaires ici?
Lawrence Johnston
2
@jmoreno: Sûrement la citation de la section 2 "Un texte JSON est un objet ou un tableau sérialisé." S'oppose à cela? JSON Lint ne pense pas non plus qu'un non-tableau ou un objet est valide. Il n'y a pas de débat sur la question de savoir si une chaîne est un littéral JSON valide; il s'agit de savoir si une chaîne en elle-même est valide.
Matt
42

Il existe au moins quatre documents qui peuvent être considérés comme des normes JSON sur Internet. Les RFC référencées décrivent toutes le type mime application/json. Voici ce que chacun a à dire sur les valeurs de niveau supérieur et si autre chose qu'un objet ou un tableau est autorisé en haut:

RFC-4627 : Non.

Un texte JSON est une séquence de jetons. L'ensemble de jetons comprend six caractères structurels, des chaînes, des nombres et trois noms littéraux.

Un texte JSON est un objet ou un tableau sérialisé.

JSON-text = objet / tableau

Notez que la RFC-4627 a été marquée «informationnelle» par opposition à «norme proposée», et qu'elle est obsolète par la RFC-7159 , qui à son tour est obsolète par la RFC-8259.

RFC-8259 : Oui.

Un texte JSON est une séquence de jetons. L'ensemble de jetons comprend six caractères structurels, des chaînes, des nombres et trois noms littéraux.

Un texte JSON est une valeur sérialisée. Notez que certaines spécifications précédentes de JSON contraignaient un texte JSON à être un objet ou un tableau. Les implémentations qui génèrent uniquement des objets ou des tableaux pour lesquels un texte JSON est demandé seront interopérables dans le sens où toutes les implémentations les accepteront comme des textes JSON conformes.

JSON-text = valeur ws ws

La RFC-8259 date de décembre 2017 et porte la mention "INTERNET STANDARD".

ECMA-262 : Oui.

La grammaire syntaxique JSON définit un texte JSON valide en termes de jetons définis par la grammaire lexicale JSON. Le symbole de but de la grammaire est JSONText.

Syntaxe JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : Oui.

Un texte JSON est une séquence de jetons formée à partir de points de code Unicode conforme à la grammaire des valeurs JSON. L'ensemble de jetons comprend six jetons structurels, des chaînes, des nombres et trois jetons de nom littéraux.

Johann
la source
10

Selon l'ancienne définition de la RFC 4627 (qui était obsolète en mars 2014 par la RFC 7159), il s'agissait toutes de «valeurs JSON» valides, mais seules les deux dernières constitueraient un «texte JSON» complet:

Un texte JSON est un objet ou un tableau sérialisé.

Selon l'analyseur utilisé, les seules "valeurs JSON" peuvent être acceptées de toute façon. Par exemple (en respectant la terminologie "valeur JSON" et "texte JSON"):

  • la JSON.parse()fonction désormais standardisée dans les navigateurs modernes accepte toute "valeur JSON"
  • la fonction PHP a json_decodeété introduite dans la version 5.2.0 n'acceptant qu'un "texte JSON" entier, mais a été modifiée pour accepter toute "valeur JSON" dans la version 5.2.1
  • Python json.loadsaccepte toute "valeur JSON" selon les exemples de cette page de manuel
  • le validateur sur http://jsonlint.com attend un "texte JSON" complet
  • le module Ruby JSON n'acceptera qu'un "texte JSON" complet (du moins selon les commentaires sur cette page de manuel )

La distinction est un peu comme la distinction entre un "document XML" et un "fragment XML", bien que techniquement <foo />soit un document XML bien formé (il serait préférable de l'écrire comme <?xml version="1.0" ?><foo />, mais comme indiqué dans les commentaires, la <?xmldéclaration est techniquement facultative ).

IMSoP
la source
La comparaison XML peut être inappropriée, car un document XML est entièrement valide sans la déclaration XML facultative. Voir la recommandation XML sur w3.org/TR/xml/#sec-well-formed
Gunther
@Gunther Ah, oui, j'avais oublié que c'était techniquement optionnel, bien que fortement encouragé.
IMSoP
@Gunther: A nitpick: <foo />est un document XML bien formé , mais pas valide . (Mais il en va de même pour <?xml version="1.0" ?><foo />.)
ruakh
@ruakh Fait intéressant, la définition ici implique que XML ne peut être "valide" que par rapport à une DTD, ce qui signifie que très peu de documents XML le sont, car les DTD sont très rarement écrits et déclarés dans la pratique (par rapport aux formats de définition de schéma tels que XSD ou RelaxNG) . Je vérifiais, parce que si vous pouviez être valide contre un schéma externe, sans le référencer, alors <foo /> peut-être ou non être valide contre un schéma particulier , mais ce n'est pas ce que dit cette norme.
IMSoP
4

La spécification ecma peut être utile pour référence:

http://www.ecma-international.org/ecma-262/5.1/

La fonction d'analyse analyse un texte JSON (une chaîne au format JSON) et produit une valeur ECMAScript. Le format JSON est une forme restreinte de littéral ECMAScript. Les objets JSON sont réalisés en tant qu'objets ECMAScript. Les tableaux JSON sont réalisés comme des tableaux ECMAScript. Les chaînes JSON, les nombres, les booléens et les valeurs nulles sont réalisés sous forme de chaînes ECMAScript, de nombres, de booléens et de null. JSON utilise un ensemble plus limité de caractères d'espace blanc que WhiteSpace et permet aux points de code Unicode U + 2028 et U + 2029 d'apparaître directement dans les littéraux JSONString sans utiliser de séquence d'échappement. Le processus d'analyse est similaire à 11.1.4 et 11.1.5 car contraint par la grammaire JSON.

JSON.parse("string"); // SyntaxError: Unexpected token s
JSON.parse(43); // 43
JSON.parse("43"); // 43
JSON.parse(true); // true
JSON.parse("true"); // true
JSON.parse(false);
JSON.parse("false");
JSON.parse("trueee"); // SyntaxError: Unexpected token e
JSON.parse("{}"); // {}
JSON.parse("[]"); // []
Emil A.
la source
4
Bien que ce soit une référence utile, il s'agit de la spécification d'un analyseur JSON particulier (celui défini dans la norme ECMAScript) et non pour le format lui-même. json.org déclare explicitement que JSON est "complètement indépendant du langage", il n'y a donc pas un analyseur correct.
IMSoP
1
JavaScript / ECMAScipt est l'inspiration de JSON, et un utilisateur de celui-ci, mais pas la "maison" de celui-ci. JSON est dérivé de la notation littérale d'objet dans (toutes les versions antérieures de) ECMAScript, mais ne lui est pas identique. La JSON.parsefonction a ensuite été ajoutée aux versions ultérieures du standard ECMAScript basé sur la grammaire de Crockford et le RFC.
IMSoP
4
Vous devriez faireJSON.parse("\"string\"");
ericbn
4

JSON signifie JavaScript Object Notation. Seulement {}et []définissez un objet Javascript. Les autres exemples sont des valeurs littérales. Il existe des types d'objet en Javascript pour travailler avec ces valeurs, mais l'expression "string"est une représentation en code source d'une valeur littérale et non d'un objet.

Gardez à l'esprit que JSON n'est pas Javascript. C'est une notation qui représente des données. Il a une structure très simple et limitée. Les données JSON sont structurées à l'aide de {},:[]caractères. Vous ne pouvez utiliser que des valeurs littérales à l'intérieur de cette structure.

Il est parfaitement valide pour un serveur de répondre avec une description d'objet ou une valeur littérale. Tous les analyseurs JSON doivent être gérés pour ne gérer qu'une valeur littérale, mais une seule valeur. JSON ne peut représenter qu'un seul objet à la fois. Donc, pour qu'un serveur renvoie plus d'une valeur, il devrait la structurer comme un objet ou un tableau.

Reactgular
la source
1
Je pense que l'approche de la réponse dans cette direction brouille plus qu'elle ne clarifie: l'origine du nom n'a aucune incidence sur les détails de la norme, et les types disponibles en JavaScript peuvent être une source d'inspiration pour les types en JSON, mais il n'y a aucune exigence qu'ils correspondent. L'introduction sur json.org le précise: "JSON est un format de texte totalement indépendant de la langue"
IMSoP
@IMSoP Je suis totalement d'accord. J'ai mélangé des types Javascript avec JSON et ce n'est pas correct. Je mettrai à jour ma réponse.
Reactgular
2

Oui, oui, oui, oui et oui. Tous sont des littéraux de valeur JSON valides.

Cependant, la RFC 4627 officielle déclare:

Un texte JSON est un objet ou un tableau sérialisé.

Ainsi, un "fichier" entier doit être constitué d'un objet ou d'un tableau en tant que structure la plus externe, qui bien sûr peut être vide. Pourtant, de nombreux analyseurs JSON acceptent également les valeurs primitives en entrée.

Bergi
la source
-1
var x;
JSON.stringify(x); // will output "{}"

Donc, votre réponse est "{}"qui désigne un objet vide.

Jani Hyytiäinen
la source
FWIW, dans Chrome, cela donne undefined, pas "{}" `
Matt
-2

Suivez simplement les schémas de chemin de fer donnés sur la page json.org . [] et {} sont les objets JSON valides minimum possibles. La réponse est donc [] et {}.

Hrishi
la source
3
Ce n'est pas un FSM, c'est une grammaire. Et cela ne semble pas indiquer quelle production est la règle de départ. Si les règles de départ étaient arrayet que objectvous auriez raison, mais il est raisonnable de s'attendre valueà être le début.
Cela me semble assez simple. Douglas Crockford les appelle ainsi et nous partons toujours de la gauche et suivons les traces vers la droite. La plus petite piste donne le JSON valide minimal.
Hrishi
2
Ce n'est pas votre interprétation d'une règle de grammaire particulière à laquelle je m'oppose, c'est que vous avez choisi deux règles et supposez que l'on ne peut partir que de celles-ci, pas d'autres. Si vous regardez la valuesrègle à la place (ou en plus) des règles arrayet object, alors les nombres et les chaînes autonomes sont un document JSON valide.
-1. Premièrement, comme le souligne @delnan, rien dans les diagrammes de json.org ne suggère qu'un texte JSON complet doit être un objet ou un tableau; vous avez choisi ces deux arbitrairement, sans vous baser sur quoi que ce soit sur json.org. Deuxièmement, pinailler la terminologie:, []alors qu'un texte JSON valide sous toutes les spécifications qui a déjà eu une opinion sur le sujet, n'est pas un "objet JSON valide", car ce n'est pas un objet JSON. «Objet» dans JSON fait spécifiquement référence à la {}notation; Les tableaux JSON ne sont pas des objets JSON.
Mark Amery