如何在Node.js中parsing包含“NaN”的JSONstring
有一个接收包含文字NaN的JSON数据string的node.js应用程序
"[1, 2, 3, NaN, 5, 6]"
这在Node.js中崩溃了JSON.parse(...)
我想parsing它,如果我可以成为一个对象。
我知道NaN
不是JSON规范的一部分。 大多数SO链接( 在JSON中发送NaN )build议修复输出。
在这里,虽然数据是在我不能控制的服务器中生成的,但是我可以通过商业Java库来查看源代码。 它是由Google的Gson库生成的:
private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create()); ... gson.toJson(data[i], Vector.class, jsonOut)
所以这似乎是一个合法的来源。 根据Gson API Javadoc,它说我应该能够parsing它:
JSON规范的2.4节不允许特殊的双精度值(NaN,Infinity,-Infinity)。 但是,Javascript规范(请参阅4.3.20,4.3.22,4.3.23节)允许这些值作为有效的Javascript值。 而且,大多数JavaScript引擎都可以在JSON中接受这些特殊的值。 因此,在实际的层面上,尽pipeJSON规范不允许这些值,但将这些值作为有效的JSON接受是合理的。
尽pipe如此,Node.js和Chrome都失败了: JSON.parse('[1,2,3,NaN,"5"]')
有没有在JSON.parse()中设置标志? 或者接受NaN
作为文字的替代parsing器?
我一直在谷歌search了一段时间,但似乎无法find关于这个问题的文件。
PHP:如何编码无限或NaN号码到JSON?
有一个接收包含文字NaN的JSON数据string的node.js应用程序
那么你的NodeJS应用程序没有收到JSON ,它接收的文本含糊其辞的JSON。 NaN
不是有效的JSON令牌。
三个选项:
1.获取源代码以正确生成JSON
这显然是首选的课程。 数据不是JSON,应该修复,这将解决您的问题。
2.以简单的方式容忍NaN
:
在parsing它之前你可以用null
replace它,例如:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));
…然后在结果中处理null
。 但是这非常简单,它不允许字符NaN
可能出现在某个string中的可能性。
或者,旋转马特球的reviver
想法(现在删除) ,你可以改变它为一个特殊的string(如"***NaN***"
),然后使用reviver用真正的NaN
取代:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, '"***NaN***"'), function(key, value) { return value === "***NaN***" ? NaN : value; });
…但是这个问题有点简单,假设字符NaN
从不出现在适当的地方。
3.使用(不寒而栗!) eval
如果您知道并信任这些数据的来源,并且不可能在传输中被篡改 ,那么您可以使用eval
来parsing它,而不是使用JSON.parse
。 由于eval
允许使用完整的JavaScript语法,包括NaN
。 希望我做了一个大胆的警告,让人们明白,我只会在非常非常非常小的情况下推荐这一点。 但是请记住, eval
允许任意执行代码,所以如果string被篡改的可能性不要使用。
当你处理任何math或行业数据时, NaN
非常方便(通常也是无穷的)。 这是自IEEE754以来的行业标准。
这显然是为什么一些图书馆,特别是GSON,让你把他们包括在他们生产的JSON,失去标准的纯度和获得理智。
当您交换复杂的dynamic对象时,复现和正则expression式解决scheme在实际项目中不可靠。
而eval
也有问题,其中之一就是事实上,当JSONstring很大时,它很容易在IE上崩溃,另外一个是安全风险。
这就是为什么我写了一个特定的parsing器(在生产中使用): JSON.parseMore
正确的解决scheme是重新编译parsing器,并向源代码贡献“allowNan”布尔标志。 这是其他库的解决scheme(python的想到)。
良好的JSON库将允许parsing几乎任何类似JSON的东西与正确的标志设置(perl的JSON.pm非常灵活)…但是当编写一条消息,他们产生标准的JSON。
IE:让房间比你find的更清洁。