来自JSON website:
JSON基于两种结构:
- 名称/值对的集合。在各种语言中,这被实现为对象,记录,结构,字典,哈希表,键控列表或关联数组。
- 有序的值列表。在大多数语言中,这被实现为数组,向量,列表或序列。
现在我有一个返回布尔值的示例服务(这是在PHP中,但它可以是任何服务器端语言):
<?php
header('Content-Type: application/json');
echo 'true';
exit;
当使用ajax(例如使用jQuery)请求此页面时:
$.ajax({
url: 'service.php',
dataType: 'json',
success: function (data) {
console.log(data);
console.log(typeof data);
}
});
结果将是:
-> true
-> boolean
我的问题是为什么允许将布尔作为JSON返回。 它与JSON定义有冲突吗?
此外,我可以在我的服务中返回数字或字符串:
<?php
header('Content-Type: application/json');
echo '2013';
exit;
结果是:
-> 2013
-> number
对于字符串:
<?php
header('Content-Type: application/json');
echo '"What is going on?"';
exit;
结果是:
-> What is going on?
-> string
答案 0 :(得分:7)
您是正确的,有效的JSON文本只能是对象或数组。我在2009年向道格拉斯·克罗克福德询问了这个问题并且证实了这一点,他说:“严格来说,它是对象|数组,就像RFC一样。&#34;
JSON RFC在第2部分中指定了这一点:
JSON文本是序列化对象或数组。
JSON-text = object / array
json.org上列出的原始JSON语法根本不清楚。它定义了所有JSON类型,但它没有说明这些类型中的哪些类型可以用作&#34; JSON文本&#34; - 完整有效的JSON。
这就是我向Doug询问的原因,他将我推荐给了RFC。不幸的是,他没有跟进我的建议,更新json.org以澄清这一点。
可能由于这种混淆,许多JSON库会很乐意为独立的字符串,数字,布尔值等创建和解析(无效)JSON,即使这些JSON并不是真正有效的JSON。
有些JSON解析器更严格。例如,jsonlint.com拒绝101
,"abc"
和true
等JSON文本。它只接受一个对象或数组。
如果您只是在自己的网络应用中生成供消费的JSON数据,那么这种区别可能并不重要。毕竟,JSON.parse()
很乐意解析它,这可能适用于所有浏览器。
但是,如果您为其他人生成JSON,那么这一点非常重要。你应该更严格地遵守标准。
我建议甚至在你自己的应用程序中关注它,部分是因为它有一个实际的好处:通过发送一个对象而不是一个简单的字符串,你有一个内置的位置,如果你需要的话,可以添加更多的信息to,以对象中的附加属性的形式。
沿着这些方向,当我定义JSON API时,我从不在最顶层使用数组。如果我拥有的是某种类型的项目数组,我仍然将它包装在一个对象中:
{
"items": [
...
]
}
部分出于同样的原因:如果我以后想要在响应中添加其他内容,那么将顶层作为对象可以轻松完成,而不会中断任何现有的客户端代码。
也许更重要的是,还有security risk with JSON arrays。 (我认为该风险仅影响使用eval()
或Function
构造函数来解析JSON,因此您可以使用JSON.parse()
安全,但我和#39;对此不是100%肯定。)
答案 1 :(得分:0)
请注意,自2013年以来,Michael Geary的答案已经过时,因为rfc7158不再将JSON文本限制为数组或对象。当前的RFC https://tools.ietf.org/html/rfc8259表示:
JSON文本是序列化的值。请注意,某些先前的 JSON规范将JSON文本限制为对象或 数组。仅生成对象或数组的实现,其中 JSON文本将在所有意义上都可互操作 实现将接受这些作为一致的JSON文本。