web-dev-qa-db-fra.com

Quel est le JSON valide minimum?

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 les JSON valides minimum possibles?

  • "string" _ La chaîne est-elle valide JSON?
  • 42 Le numéro simple est-il valide JSON?
  • 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?
150
bessarabov

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

Cela signifie que seulement {} Et [] Sont des chaînes JSON complètes et valides dans les analyseurs et les stringifiers qui adhèrent à cette norme. .

Cependant , l'introduction de l'ECMA-404 change cela, et l'avis mis à jour peut être lu ici . J'ai aussi écrit un billet de blog sur le sujet.


Cependant, pour compliquer davantage les choses, l’objet JSON (par exemple, JSON.parse() et JSON.stringify()) disponible dans les navigateurs Web est normalisé dans ES5 , et qui 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 la RFC 4627, à deux exceptions près:

  • La production JSONText de niveau supérieur de la grammaire JSON ECMAScript peut consister en une valeur JSON plutôt que d'être limitée à un objet JSON ou à un tableau JSON, comme spécifié par le RFC 4627.

  • coupé

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

Notez que vous pouvez donc hiérarchiser un nombre dans un navigateur conforme via JSON.stringify(5), qui serait rejeté par un autre analyseur conforme à la RFC4627, mais pour lequel l'exception spécifique ne figure pas ci-dessus. Ruby, par exemple, semblerait être un exemple de ce type seulement accepte les objets et les tableaux en tant que racine . PHP, d’autre part, ajoute spécifiquement l’exception que "cela encodera et décodera également les types scalaires et NULL".

132
Matt

Au moins quatre documents peuvent être considérés comme des normes JSON sur Internet. Les RFC référencés décrivent tous le type mime application/json. Voici ce que chacun a à dire sur les valeurs de niveau supérieur, et si tout ce qui est autre 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 était marquée "informative" par opposition à la "norme proposée" et qu'elle est obsolète par RFC-7159 , elle-même obsolète pour 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 ont contraint un texte JSON à être un objet ou un tableau. Les implémentations qui génèrent uniquement des objets ou des tableaux dans lesquels un texte JSON est appelé seront interopérables dans le sens où toutes les implémentations les accepteront comme des textes JSON conformes.

JSON-text = ws valeur ws

La RFC-8259 est datée 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és à partir de points de code Unicode conformes à la grammaire des valeurs JSON. L'ensemble de jetons comprend six jetons structurels, des chaînes, des nombres et trois jetons de nom littéral.

39
Johann

Selon l'ancienne définition de RFC 4627 (obsolète en mars 2014 par le RFC 7159), il s'agissait 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 "valeurs JSON" peuvent être acceptées de toute façon. Par exemple (en s’appuyant sur la terminologie "valeur JSON" vs "texte JSON"):

  • la fonction JSON.parse() maintenant normalisée dans les navigateurs modernes accepte toutes les "valeurs JSON"
  • la PHP fonction json_decode a été introduit dans la version 5.2.0 en acceptant uniquement un "texte JSON" entier, mais a été modifié pour accepter toute "valeur JSON" dans la version 5.2.1.
  • Python's json.loads accepte toute "valeur JSON" selon des exemples sur cette page de manuel
  • le validateur de http://jsonlint.com attend un "texte JSON" complet
  • le module JSON Ruby n'acceptera qu'un "texte JSON" complet (au moins selon les commentaires sur cette page de manuel )

La distinction ressemble un peu à la distinction entre un "document XML" et un "fragment XML", bien que techniquement <foo /> est un document XML bien formé (il serait préférable de l’écrire sous la forme <?xml version="1.0" ?><foo />, mais comme indiqué dans les commentaires, le <?xml la déclaration est techniquement optionnelle).

9
IMSoP

JSON signifie JavaScript Object Notation. Seulement {} et [] définir un objet Javascript. Les autres exemples sont des littéraux de valeur. Il existe des types d’objets 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. Sa structure est très simple et limitée. Les données JSON sont structurées à l'aide de {},:[] personnages. 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 manipulés pour gérer uniquement une valeur littérale, mais une seule valeur. JSON ne peut représenter qu'un seul objet à la fois. Ainsi, pour qu'un serveur renvoie plus d'une valeur, il doit le structurer en tant qu'objet ou tableau.

4
Reactgular

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

Cependant, le document officiel RFC 4627 indique:

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

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

2
Bergi

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 génère 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 sous la forme de tableaux ECMAScript. Les chaînes, nombres, booléens et null JSON sont réalisés en tant que chaînes, nombres, booléens et null ECMAScript. JSON utilise un ensemble plus limité de caractères d'espacement 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 tel que 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("[]"); // []
2
Emil A.