有一个node.js应用程序,该应用程序接收包含文字NaN的JSON数据字符串,例如
"[1, 2, 3, NaN, 5, 6]"
这会导致Node.js中的JSON.parse(...)
崩溃。如果可以的话,我想将其解析为一个对象。
我知道NaN
不是JSON规范的一部分。大多数SO链接(sending NaN in json)建议修复输出。
在这里,虽然数据是在一个我不控制的服务器上产生的,但它是由一个商业Java库产生的,我可以在那里看到源代码,而且它是由Google的Gson库产生的:
private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create());
...
gson.toJson(data[i], Vector.class, jsonOut)
所以这看起来像是一个合法的源代码。根据Gson API Javadoc,它说我应该能够解析它:
JSON规范的第2.4节不允许特殊的双精度值(NaN,无穷大,-无穷大)。然而,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
作为文字?
我已经在谷歌上搜索了一段时间,但似乎找不到一个关于这个问题的医生。
PHP:如何将无穷大或NaN数字编码为JSON?
5条答案
按热度按时间tyu7yeag1#
有一个node.js应用程序,该应用程序接收包含文字NaN的JSON数据字符串,例如
那么你的NodeJS应用不是在接收JSON,而是在接收类似JSON的文本。
NaN
不是一个有效的JSON令牌。三个选项:
1.获取源代码以正确生成JSON
这显然是首选的方法。数据不是JSON,应该被修复,这将修复您的问题。
2.以简单的方式容忍
NaN
:您可以在解析它之前将其替换为
null
,例如:......然后在结果中处理
null
。但这是非常简单的,它不允许字符NaN
出现在字符串的某个地方。或者,旋转Matt Ball的
reviver
idea (现已删除),您可以将其更改为一个特殊字符串(如"***NaN***"
),然后使用reviver将其替换为真实的的NaN
:......但这也有同样的问题,即思想有点简单,假设字符
NaN
从未出现在适当的位置。3.使用 (颤抖!)
eval
如果您知道并信任此数据的来源,并且数据在传输过程中不可能被篡改,则可以使用
eval
而不是JSON.parse
来解析数据。由于eval
支持完整的JavaScript语法,包括NaN
,这是可行的。希望我的警告足够大胆,让人们明白我只会在非常,非常,* 非常 * 的情况下推荐这一点。但再次,记住eval
允许任意执行代码,所以如果字符串有任何被篡改的可能性,不要使用它。v1l68za42#
当你处理任何数学或工业数据时,
NaN
非常方便(无穷大也是如此),它是自IEEE754以来的一个工业标准。显然,这就是为什么有些库,特别是GSON,允许您将它们包含在它们生成的JSON中,从而失去了标准的纯粹性并获得了合理性。
当您交换复杂的动态对象时,Revival和regex解决方案在真实的项目中不能可靠地使用。
eval
也有问题,其中之一是当JSON字符串很大时,它在IE上很容易崩溃,另一个问题是安全风险。这就是为什么我写了一个特定的解析器(用于生产):JSON.parseMore
iyr7buue3#
你可以使用JSON5.library.a从工程页面中引用:
JSON5数据交换格式(英语:JSON5 Data Interchange Format,缩写为JSON5)是JSON的一个超集,其目的是通过扩展JSON的语法以包含ECMAScript 5.1的一些结果来减轻JSON的一些限制。
这个JavaScript库是JSON5解析和序列化库的官方参考实现。
正如你所期望的,它确实支持解析NaN(与Python等序列化它们的方式兼容):
7gs2gvoe4#
正确的解决方案是重新编译解析器,并为源代码库提供一个“allowNan”布尔标志,这是其他库的解决方案(python的解决方案)。
好的JSON库可以通过设置正确的标志来解析几乎任何与JSON有点相似的内容(perl的JSON.pm非常灵活)...但是在编写消息时,它们会生成标准的JSON。
IE:让房间比你发现的时候更干净。
zfycwa2u5#
只是一个小补充TJ克劳德的已经足够全面的答复,我宁愿使用
因为我实际上需要知道它是否是NaN值。
我也会在fetch或axios GET请求中这样做,只有在默认JSON解析失败并且数据以字符串形式出现时。