How to parse JSON string containing “NaN” in Node.js

后端 未结 4 1404
盖世英雄少女心
盖世英雄少女心 2020-12-17 08:24

Have a node.js app that is receiving JSON data strings that contain the literal NaN, like

 \"[1, 2, 3, NaN, 5, 6]\"

This crashes JSON

相关标签:
4条回答
  • 2020-12-17 09:00

    You can use JSON5 library. A quote from the project page:

    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.

    As you would expect, among other things it does support parsing NaNs (compatible with how Python and the like serialize them):

    JSON5.parse("[1, 2, 3, NaN, 5, 6]")
    > (6) [1, 2, 3, NaN, 5, 6]
    
    0 讨论(0)
  • 2020-12-17 09:01

    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).

    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.

    IE: leave the room cleaner than you found it.

    0 讨论(0)
  • 2020-12-17 09:16

    Have a node.js app that is receiving JSON data strings that contain the literal NaN, like

    Then your NodeJS app isn't receiving JSON, it's receiving text that's vaguely JSON-like. NaN is not a valid JSON token.

    Three options:

    1. Get the source to correctly produce JSON

    This is obviously the preferred course. The data is not JSON, that should be fixed, which would fix your problem.

    2. Tolerate the NaN in a simple-minded way:

    You could replace it with null before parsing it, e.g.:

    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 NaN might appear in a string somewhere.

    Alternately, spinning Matt Ball's reviver idea (now deleted), you could change it to a special string (like "***NaN***") and then use a reviver to replace that with the real 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 NaN never appear in an appropriate place.

    3. Use (shudder!) 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 eval to parse it instead of JSON.parse. Since eval allows 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, very tiny percentage of situations. But again, remember eval allows arbitrary execution of code, so if there's any possibility of the string having been tampered with, don't use it.

    0 讨论(0)
  • 2020-12-17 09:17

    When you deal with about anything mathematical or with industry data, NaN is terribly convenient (and often infinities too are). And it's an industry standard since IEEE754.

    That's obviously why some libraries, notably GSON, let you include them in the JSON they produce, losing standard purity and gaining sanity.

    Revival and regex solutions aren't reliably usable in a real project when you exchange complex dynamic objects.

    And eval has 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.

    That's why I wrote a specific parser (used in production) : JSON.parseMore

    0 讨论(0)
提交回复
热议问题