Comment analyser chaîne JSON contenant “NaN” dans Node.js
Ont un node.js application qui reçoit les données JSON chaînes qui contiennent le littéral NaN, comme
"[1, 2, 3, NaN, 5, 6]"
Cela se bloque JSON.parse(...)
dans Node.js. Je tiens à analyser, si je peux dans un objet.
Je sais NaN
ne fait pas partie de la spécification JSON. La plupart des liens (envoi NaN en json) suggèrent de fixer la sortie.
Ici, si les données sont produites dans un serveur que je ne contrôle pas, c'est par un commercial bibliothèque Java où je peux voir le code source. Et c'est produit par Google Gson bibliothèque:
private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create());
...
gson.toJson(data[i], Vector.class, jsonOut)
De sorte que semble comme une source légitime. Et selon la Gson API Javadoc il dit que je devrais être en mesure de l'analyser:
La Section 2.4 du JSON spécification interdit spécial double des valeurs
(NaN, L'Infini, L'Infini). Cependant, Javascript cahier des charges (voir
section 4.3.20, 4.3.22, 4.3.23) permet à ces valeurs comme valide
Javascript valeurs. En outre, la plupart des moteurs JavaScript accepte ces
valeurs spéciales en JSON sans problème. Ainsi, à un niveau pratique, il
fait sens pour accepter ces valeurs sous forme de JSON valide même si JSON
spécification empêche.
Malgré cela, il échoue dans les deux Node.js et Chrome: JSON.parse('[1,2,3,NaN,"5"]')
Est-il un indicateur de mettre en JSON.parse()? Ou un autre analyseur qui accepte NaN
comme un littéral?
J'ai cherché sur Google, mais n'arrive pas à trouver une doc sur cette question.
PHP: Comment coder l'infini ou NaN numéros de JSON?
nœud de parser JSON suit tout simplement la spec. Le "ironie" est seulement une violation de la le principe de robustesse.
Non, l'ironie est qu'un projet Google dit que "la plupart des moteurs JavaScript va accepter ces valeurs spéciales en JSON sans problème" alors que Google est le moteur JavaScript est l'une des exceptions, comme en témoigne le fait que Chrome n'aime pas la chaîne.
"La Section 1.2 décrit JSON. Cependant, le protocole TCP/IP prend en charge de nombreux autres formats, vous devriez être en mesure de décoder, compte tenu de l'effort suffisant ou le mépris pour la sécurité. Par conséquent, nous avons pensé, pourquoi se limiter à JSON?" - Google
OriginalL'auteur prototype | 2013-03-05
Vous devez vous connecter pour publier un commentaire.
Ensuite votre application NodeJS n'est pas réception JSON, c'est la réception d'un texte vaguement JSON.
NaN
n'est pas un JSON valide jeton.Trois options:
1. Obtenir le code source pour produire correctement JSON
C'est évidemment la meilleure solution. Les données ne sont pas JSON, qui doit être fixé, ce qui permettrait de résoudre votre problème.
2. Tolérer la
NaN
dans un simple d'esprit:Vous pouvez le remplacer avec
null
avant l'analyse, par exemple:...et puis de gérer la
null
s dans le résultat. Mais c'est très simple d'esprit, il ne tient pas compte de la possibilité que les personnagesNaN
peut apparaître dans une chaîne de caractères quelque part.Alternativement, la filature de Matt de la Balle
reviver
idée (maintenant supprimé), vous pouvez le changer pour une chaîne de caractères spéciaux (comme"***NaN***"
) et ensuite utiliser un rénovateur de la remplacer par de la vraieNaN
:...mais qui a le même problème d'être un peu simple d'esprit, en supposant que les personnages
NaN
n'apparaissent jamais dans un endroit approprié.3. Utilisation (frisson!)
eval
Si vous connaissez et de confiance à la source de ces données et il n'y a PAS de possibilité d'être altéré en transit, alors vous pouvez utiliser
eval
à analyser au lieu deJSON.parse
. Depuiseval
permet toute la syntaxe JavaScript, y comprisNaN
, qui fonctionne. Heureusement, j'ai fait la mise en garde de l'audace, pour que les gens comprennent que je recommanderais ceci à un très, très, très infime pourcentage de situations. Mais encore une fois, rappelez-vouseval
permet l'exécution arbitraire de code, donc si il y a possibilité de la chaîne ayant été altéré, ne l'utilisez pas.Wow! Je faisait des siennes à la honte de ne pas trouver un bien documentée option. Donc, sur le bon côté des choses, il semble que l'option n'est pas là pour être trouvé.
LOL en Effet pas. 🙂 Content que contribué à!
Très réfléchie réponses. Chaîne de remplacer les œuvres pour l'instant. Mais les fichiers de données sont diverses arbitraire et fourni par l'utilisateur, de sorte pourrait très bien contenir "NaN" dans une colonne de texte, et le souci de la fonction eval() est également valide. Vais voir si je peux obtenir la bibliothèque elle-même changé. Merci!
Je suis allé avec l'option 3, et il vaut la peine de mentionner que vous devez ajouter parenthèse à l'entrée:
function myParseJSON(almost_json) { return eval("(" + almost_json + ")") }
OriginalL'auteur
Quand vous avez affaire avec n'importe quoi mathématique ou avec les données de l'industrie,
NaN
est très pratique (et souvent les infinis sont aussi). Et c'est un standard de l'industrie depuis IEEE754.Évidemment c'est pourquoi certaines bibliothèques, notamment GSON, vous permettent de les inclure dans le JSON qu'ils produisent, perdre de la norme de pureté et d'acquérir de la santé mentale.
Réveil et la regex solutions ne sont pas fiable utilisable dans un véritable projet lors de l'échange dynamique complexe des objets.
Et
eval
a des problèmes aussi, l'un d'eux est le fait que c'est sujette à des crash sur IE lorsque la chaîne JSON est grand, l'autre étant les risques de sécurité.C'est pourquoi j'ai écrit un analyseur spécifique (utilisé dans la production) : JSON.parseMore
OriginalL'auteur
La bonne solution est de recompiler l'analyseur, et de contribuer à une "allowNan" drapeau booléen à la base de la source. C'est la solution d'autres bibliothèques ont (python vient à l'esprit).
Bonne JSON bibliothèques permissivité analyser juste au sujet de quelque chose ressemblant vaguement à du JSON avec le droit indicateurs définis (perl JSON.h est notamment flexible)... mais lors de l'écriture d'un message qu'ils produisent standard JSON.
IE: quitter la chambre plus propre que vous l'avez trouvé.
OriginalL'auteur
Vous pouvez utiliser JSON5 de la bibliothèque. Une citation de la page du projet:
Que vous attendez, entre autres choses, il prend en charge l'analyse NaNs (compatible avec la façon Python et la comme sérialiser):
OriginalL'auteur