From JSON website:
JSON is built on two structures:
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
Now I have a sample service that returns a boolean (this is in PHP, but it could be any server side language):
<?php
header('Content-Type: application/json');
echo 'true';
exit;
And when requesting this page with ajax (for example with jQuery):
$.ajax({
url: 'service.php',
dataType: 'json',
success: function (data) {
console.log(data);
console.log(typeof data);
}
});
The result would be:
-> true
-> boolean
My question is why it's allowed to return boolean as a JSON. Doesn't it have conflict with JSON definition?
ALSO
Also I can return number or string in my service:
<?php
header('Content-Type: application/json');
echo '2013';
exit;
And the result is:
-> 2013
-> number
And for string:
<?php
header('Content-Type: application/json');
echo '"What is going on?"';
exit;
And the result is:
-> What is going on?
-> string
From JSON website:
JSON is built on two structures:
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
Now I have a sample service that returns a boolean (this is in PHP, but it could be any server side language):
<?php
header('Content-Type: application/json');
echo 'true';
exit;
And when requesting this page with ajax (for example with jQuery):
$.ajax({
url: 'service.php',
dataType: 'json',
success: function (data) {
console.log(data);
console.log(typeof data);
}
});
The result would be:
-> true
-> boolean
My question is why it's allowed to return boolean as a JSON. Doesn't it have conflict with JSON definition?
ALSO
Also I can return number or string in my service:
<?php
header('Content-Type: application/json');
echo '2013';
exit;
And the result is:
-> 2013
-> number
And for string:
<?php
header('Content-Type: application/json');
echo '"What is going on?"';
exit;
And the result is:
-> What is going on?
-> string
Share
edited Jun 20, 2020 at 9:12
CommunityBot
11 silver badge
asked Jun 6, 2013 at 6:33
user2417834user2417834
4
- 1 It's returned as json to allow cross site ajax requests – Jordan Doyle Commented Jun 6, 2013 at 6:36
- If all you could return were arrays or objects, what would the contents of these collections be? You eventually need scalar objects as the leaves. – Barmar Commented Jun 6, 2013 at 6:51
- @Barmar - a "JSON text" can only be an array or an object according to the RFC. However, inside that array or object you can use any of the other JSON data types. – Michael Geary Commented Jun 6, 2013 at 6:53
- Related if not duplicate: stackoverflow./q/18419428/11683 – GSerg Commented Oct 8, 2016 at 19:00
2 Answers
Reset to default 9You are correct that a valid JSON text can only be an object or an array. I asked Douglas Crockford about this in 2009 and he confirmed it, saying "Strictly speaking, it is object|array, as in the RFC."
The JSON RFC specifies this in section 2:
A JSON text is a serialized object or array.
JSON-text = object / array
The original JSON syntax listed on json does not make this clear at all. It defines all of the JSON types, but it doesn't say anywhere which of these types may be used as a "JSON text" - a plete valid piece of JSON.
That's why I asked Doug about it and he referred me to the RFC. Unfortunately, he didn't follow up on my suggestion to update json to clarify this.
Probably because of this confusion, many JSON libraries will happily create and parse (invalid) JSON for a standalone string, number, boolean, etc. even though those aren't really valid JSON.
Some JSON parsers are more strict. For example, jsonlint. rejects JSON texts such as 101
, "abc"
, and true
. It only accepts an object or array.
This distinction may not matter much if you're just generating JSON data for consumption in your own web app. After all, JSON.parse()
is happy to parse it, and that probably holds true in all browsers.
But it is important if you ever generate JSON for other people to use. There you should follow the standard more strictly.
I would suggest following it even in your own app, partly because there's a practical benefit: By sending down an object instead of a bare string, you have a built-in place to add more information if you ever need to, in the form of additional properties in the object.
Along those lines, when I'm defining a JSON API, I never use an array at the topmost level. If what I have is an array of items of some sort, I still wrap it in an object:
{
"items": [
...
]
}
This is partly for the same reason: If I later want to add something else to the response, having the top level be an object makes that easy to do without disrupting any existing client code.
Perhaps more importantly, there's also a possible security risk with JSON arrays. (I think that risk only affects the use of eval()
or the Function
constructor to parse JSON, so you're safe with JSON.parse()
, but I'm not 100% sure on this.)
Note, the answer from Michael Geary is outdated since rfc7158 in 2013 which does not limit JSON text to array or object anymore. The current RFC https://www.rfc-editor/rfc/rfc8259 says:
A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array. Implementations that generate only objects or arrays where a JSON text is called for will be interoperable in the sense that all implementations will accept these as conforming JSON texts.