Ionică Bizău
Ionică Bizău

Reputation: 113355

Can JSON.parse() indicate a valid JSON format?

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

Answers (2)

nmaier
nmaier

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

Bergi
Bergi

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

Related Questions