Reputation: 113355
For a long time I used try - catch
to be sure that a string is a valid JSON. Today I found that JSON.parse(1)
(a number) returns 1
and JSON.parse("123")
returns "123"
while I expect a syntax error like: Expecting '{', '['
.
Even this answer doesn't seem to solve my problem.
So, the question is: can JSON.parse() indicate if the argument that I pass there has a correct JSON format or not?
If not, which is the alternative?
Upvotes: 0
Views: 231
Reputation: 33162
The grammar given in ECMA-262 15.12.1.2 - The JSON Syntactic Grammar states:
JSONText :
JSONValue
JSONValue :
JSONNullLiteral
JSONBooleanLiteral
JSONObject
JSONArray
JSONString
JSONNumber
Therefore plain primitive type values are actually valid JSON. Your expectation that only arrays and complex objects are valid JSON is wrong.
JSON.parse(1)
will be coerced to a string, so it is equivalent to JSON.parse("1")
. And 1
is a valid JSONValue
and therefore a valid JSONText
resulting in the the parser just returning 1
again. Same with JSON.parse("123")
.
The ECMA-262 grammar seems to differ from the one given in RFC 4627, but expect browsers to follow ECMA rather than the RFC.
PS: You may still validate further with something like:
var v = JSON.parse(jsonString);
if (v !== new Object(v)) { // Also: works when v = null
throw new Error("Not an Object/Array");
}
Upvotes: 2
Reputation: 664434
Can JSON.parse() indicate if the argument that I pass there has a correct JSON format or not?
Yes, that's what it does. Only there are two different definitions of "correct". While the official RFC says JSON-text = object / array
, the EcmaScript JSON Grammar is more liberal and considers every JSONValue
to be a JSONText
. JSON.parse
does work as expected.
If you want to restrict the accepted values to object and array notations, simply use
var result = JSON.parse(string);
if (result !== Object(result)) // typeof result != 'object' || result == null
throw new Error("JSON.parse: Object or Array literal expected, got: "+typeof result);
Upvotes: 2