如何在 Node.js 中解析包含“NaN”的 JSON 字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15228651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to parse JSON string containing "NaN" in Node.js
提问by prototype
Have a node.js app that is receiving JSON data strings that contain the literal NaN, like
有一个 node.js 应用程序接收包含文字 NaN 的 JSON 数据字符串,例如
"[1, 2, 3, NaN, 5, 6]"
This crashes JSON.parse(...)in Node.js. I'd like to parse it, if i can into an object.
这会JSON.parse(...)在 Node.js 中崩溃。如果我可以解析它,我想解析它。
I know NaNis not part of JSON spec. Most SO links (sending NaN in json) suggest to fix the output.
我知道NaN这不是 JSON 规范的一部分。大多数 SO 链接(在 json 中发送 NaN)建议修复输出。
Here, though the data is produced in a server I don't control, it's by a commercial Java library where I can see the source code. And it's produced by Google's Gson library:
在这里,虽然数据是在我无法控制的服务器中生成的,但它是由商业 Java 库生成的,我可以在其中查看源代码。它是由 Google 的 Gson 库生成的:
private Gson gson = (new GsonBuilder().serializeSpecialFloatingPointValues().create());
...
gson.toJson(data[i], Vector.class, jsonOut)
So that seems like a legitimate source. And according to the Gson API Javadocit says I should be able to parse it:
所以这似乎是一个合法的来源。根据Gson API Javadoc它说我应该能够解析它:
Section 2.4 of JSON specification disallows special double values (NaN, Infinity, -Infinity). However, Javascript specification (see section 4.3.20, 4.3.22, 4.3.23) allows these values as valid Javascript values. Moreover, most JavaScript engines will accept these special values in JSON without problem. So, at a practical level, it makes sense to accept these values as valid JSON even though JSON specification disallows them.
JSON 规范的第 2.4 节不允许特殊的双精度值(NaN、Infinity、-Infinity)。但是,Javascript 规范(请参阅第 4.3.20、4.3.22、4.3.23 节)允许这些值作为有效的 Javascript 值。此外,大多数 JavaScript 引擎都可以毫无问题地接受 JSON 中的这些特殊值。因此,在实际层面上,即使 JSON 规范不允许这些值,接受这些值作为有效的 JSON 也是有意义的。
Despite that, this fails in both Node.js and Chrome: JSON.parse('[1,2,3,NaN,"5"]')
尽管如此,这在 Node.js 和 Chrome 中都失败了: JSON.parse('[1,2,3,NaN,"5"]')
Is there a flag to set in JSON.parse()? Or an alternative parser that accepts NaNas a literal?
JSON.parse() 中是否有要设置的标志?或者接受NaN作为文字的替代解析器?
I've been Googling for a while but can't seem to find a doc on this issue.
我一直在谷歌搜索一段时间,但似乎无法找到关于这个问题的文档。
回答by T.J. Crowder
Have a node.js app that is receiving JSON data strings that contain the literal NaN, like
有一个 node.js 应用程序接收包含文字 NaN 的 JSON 数据字符串,例如
Then your NodeJS app isn'treceiving JSON, it's receiving text that's vaguely JSON-like. NaNis not a valid JSON token.
然后您的 NodeJS 应用程序没有接收JSON,它接收的文本有点类似于 JSON 。NaN不是有效的 JSON 令牌。
Three options:
三个选项:
1. Get the source to correctly produce JSON
1.获取正确生成JSON的源码
This is obviously the preferred course. The data is not JSON, that should be fixed, which would fix your problem.
这显然是首选课程。数据不是 JSON,应该是固定的,这可以解决您的问题。
2. Tolerate the NaNin a simple-minded way:
2.NaN以简单的方式容忍:
You could replace it with nullbefore parsing it, e.g.:
您可以null在解析之前将其替换为,例如:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, "null"));
...and then handle nulls in the result. But that's very simple-minded, it doesn't allow for the possibility that the characters NaNmight appear in a string somewhere.
...然后null在结果中处理s。但这很简单,它不允许字符NaN出现在某个字符串中的可能性。
Alternately, spinning Matt Ball's reviveridea (now deleted), you could change it to a special string (like "***NaN***") and then use a reviver to replace that with the real NaN:
或者,旋转 Matt Ball 的reviver想法(现已删除),您可以将其更改为特殊字符串(如"***NaN***"),然后使用 reviver 将其替换为真实的NaN:
var result = JSON.parse(yourString.replace(/\bNaN\b/g, '"***NaN***"'), function(key, value) {
return value === "***NaN***" ? NaN : value;
});
...but that has the same issue of being a bit simple-minded, assuming the characters NaNnever appear in an appropriate place.
...但这也有同样的问题,那就是有点头脑简单,假设角色NaN永远不会出现在合适的地方。
3. Use (shudder!)eval
3.使用(颤抖!)eval
If you know and trust the source of this data and there's NO possibility of it being tampered with in transit, then you could use evalto parse it instead of JSON.parse. Since evalallows full JavaScript syntax, including NaN, that works. Hopefully I made the caveat bold enough for people to understand that I would only recommend this in a very, very, verytiny percentage of situations. But again, remember evalallows arbitrary execution of code, so if there's any possibility of the string having been tampered with, don't use it.
如果您知道并信任此数据的来源,并且在传输过程中不可能被篡改,那么您可以使用eval来解析它而不是JSON.parse. 因为eval允许完整的 JavaScript 语法,包括NaN,所以有效。希望我的警告足够大胆,让人们明白我只会在非常、非常、非常小的情况下推荐这个。但同样,请记住eval允许任意执行代码,因此如果字符串可能被篡改,请不要使用它。
回答by Denys Séguret
When you deal with about anything mathematical or with industry data, NaNis terribly convenient (and often infinities too are). And it's an industry standard since IEEE754.
当您处理任何数学或行业数据时,NaN非常方便(通常无穷大也是如此)。它是自 IEEE754 以来的行业标准。
That's obviously why some libraries, notably GSON, let you include them in the JSON they produce, losing standard purity and gaining sanity.
这显然就是为什么一些库,尤其是 GSON,让你将它们包含在它们生成的 JSON 中,从而失去了标准的纯度并获得了理智。
Revival and regex solutions aren't reliably usable in a real project when you exchange complex dynamic objects.
当您交换复杂的动态对象时,复兴和正则表达式解决方案在实际项目中不可靠。
And evalhas problems too, one of them being the fact it's prone to crash on IE when the JSON string is big, another one being security risks.
并且eval也有问题,其中之一是当 JSON 字符串很大时它很容易在 IE 上崩溃,另一个是安全风险。
That's why I wrote a specific parser (used in production) : JSON.parseMore
这就是为什么我写了一个特定的解析器(用于生产):JSON.parseMore
回答by nirvana-msu
You can use JSON5library. A quote from the project page:
您可以使用JSON5库。来自项目页面的引用:
The JSON5 Data Interchange Format (JSON5) is a superset of JSON that aims to alleviate some of the limitations of JSON by expanding its syntax to include some productions from ECMAScript 5.1.
This JavaScript library is the official reference implementation for JSON5 parsing and serialization libraries.
JSON5 数据交换格式 (JSON5) 是 JSON 的超集,旨在通过扩展其语法以包括来自 ECMAScript 5.1 的一些产品来减轻 JSON 的一些限制。
这个 JavaScript 库是 JSON5 解析和序列化库的官方参考实现。
As you would expect, among other things it does support parsing NaNs (compatible with how Python and the like serialize them):
如您所料,除其他外,它确实支持解析 NaN(与 Python 等序列化它们的方式兼容):
JSON5.parse("[1, 2, 3, NaN, 5, 6]")
> (6) [1, 2, 3, NaN, 5, 6]
回答by Erik Aronesty
The correct solution is to recompile the parser, and contribute an "allowNan" boolean flag to the source base. This is the solution other libraries have (python's comes to mind).
正确的解决方案是重新编译解析器,并为源代码库贡献一个“allowNan”布尔标志。这是其他库的解决方案(想到了python)。
Good JSON libraries will permissively parse just about anything vaguely resembling JSON with the right flags set (perl's JSON.pm is notably flexible)... but when writing a message they produce standard JSON.
好的 JSON 库将允许使用正确的标志集(perl 的 JSON.pm 非常灵活)来解析几乎任何与 JSON 相似的东西……但是在编写消息时,它们会生成标准的 JSON。
IE: leave the room cleaner than you found it.
IE:让房间比你发现的更干净。

