次のようなリテラルNaNを含むJSONデータ文字列を受信するnode.jsアプリがあります。
_ "[1, 2, 3, NaN, 5, 6]"
_
これにより、Node.jsのJSON.parse(...)
がクラッシュします。私がオブジェクトにできる場合は、それを解析したいと思います。
NaN
はJSON仕様の一部ではないことを私は知っています。ほとんどのSOリンク( jsonでNaNを送信 )は出力を修正することを提案します。
ここでは、データは私が制御していないサーバーで生成されていますが、ソースコードを表示できる商用Javaライブラリによって生成されています。また、GoogleのGsonライブラリによって生成されています。
_private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create());
...
gson.toJson(data[i], Vector.class, jsonOut)
_
ですから、それは正当な情報源のようです。そして Gson API Javadoc によれば、それを解析できるはずです。
JSON仕様のセクション2.4では、特別なdouble値(NaN、Infinity、-Infinity)は許可されていません。ただし、Javascript仕様(セクション4.3.20、4.3.22、4.3.23を参照)では、これらの値を有効なJavascript値として許可しています。さらに、ほとんどのJavaScriptエンジンは、JSONでこれらの特別な値を問題なく受け入れます。したがって、実用的なレベルでは、JSON仕様で許可されていなくても、これらの値を有効なJSONとして受け入れることは理にかなっています。
それにもかかわらず、これはNode.jsとChromeの両方で失敗します:JSON.parse('[1,2,3,NaN,"5"]')
JSON.parse()に設定するフラグはありますか?または、NaN
をリテラルとして受け入れる代替パーサー?
私はしばらくグーグルをしていますが、この問題に関するドキュメントが見つからないようです。
次のようなリテラルNaNを含むJSONデータ文字列を受信するnode.jsアプリがあります。
次に、NodeJSアプリは受信しません[〜#〜] json [〜#〜] を受信しますJSONのような。 NaN
は有効なJSONトークンではありません。
3つのオプション:
これは明らかに好ましいコースです。データはJSONではないため、修正する必要があります。これにより、問題が修正されます。
NaN
を許容します。解析する前に、null
に置き換えることができます。例:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));
...そして結果のnull
sを処理します。しかし、それは非常に単純な考え方であり、文字NaN
が文字列のどこかに現れる可能性を考慮に入れていません。
または、MattBallのreviver
アイデア(現在は削除されています)を回転させて、特別な文字列("***NaN***"
など)に変更してから、リバイバーを使用することもできます。これを実際のNaN
に置き換えるには:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, '"***NaN***"'), function(key, value) {
return value === "***NaN***" ? NaN : value;
});
...しかし、文字NaN
が適切な場所に表示されないと仮定すると、少し単純であるという同じ問題があります。
eval
を使用しますこのデータのソースを知っていて信頼していて、転送中に改ざんされる可能性がない場合、その後、JSON.parse
の代わりにeval
を使用して解析できます。 eval
は、NaN
を含む完全なJavaScript構文を許可するため、機能します。うまくいけば、私がこれを非常に、非常に、非常にごくわずかな割合の状況でのみ推奨することを人々が理解できるように、警告を大胆にした。ただし、eval
はコードの任意の実行を許可するため、文字列が改ざんされている可能性がある場合は使用しないでください。
数学的または業界データを扱う場合、NaN
は非常に便利です(多くの場合、無限大も便利です)。そしてそれはIEEE754以来の業界標準です。
そのため、GSONなどの一部のライブラリでは、ライブラリを生成するJSONに含めることができるため、標準の純粋さが失われ、健全性が高まります。
複雑な動的オブジェクトを交換する場合、実際のプロジェクトでリバイバルソリューションと正規表現ソリューションを確実に使用することはできません。
また、eval
にも問題があります。その1つは、JSON文字列が大きい場合にIEでクラッシュする傾向があるという事実であり、もう1つはセキュリティリスクです。
そのため、特定のパーサー(本番環境で使用)を作成しました: JSON.parseMore
JSON5 ライブラリを使用できます。プロジェクトページからの引用:
JSON5データ交換フォーマット(JSON5)は、JSONのスーパーセットであり、構文を拡張してECMAScript 5.1の一部のプロダクションを含めることにより、JSONの制限の一部を緩和することを目的としています。
このJavaScriptライブラリは、JSON5解析およびシリアル化ライブラリの公式リファレンス実装です。
ご想像のとおり、特にNaNの解析をサポートしています(Pythonなどでシリアル化する方法と互換性があります):
JSON5.parse("[1, 2, 3, NaN, 5, 6]")
> (6) [1, 2, 3, NaN, 5, 6]
正しい解決策は、パーサーを再コンパイルし、「allowNan」ブールフラグをソースベースに提供することです。これは他のライブラリが持っている解決策です(Pythonが思い浮かびます)。
優れたJSONライブラリは、適切なフラグが設定されたJSONに漠然と似ているものを許容的に解析します(PerlのJSON.pmは特に柔軟性があります)...しかし、メッセージを書き込むと、標準のJSONが生成されます。
IE:見つけたよりも部屋をきれいにしておいてください。