Javascript 为什么JSON结果可以是布尔值而不是对象或数组?

Javascript 为什么JSON结果可以是布尔值而不是对象或数组?,javascript,ajax,json,Javascript,Ajax,Json,发件人: JSON构建在两种结构上: 名称/值对的集合。在各种语言中,这是作为对象、记录、结构、字典、哈希表、键控列表或关联数组实现的 值的有序列表。在大多数语言中,这是以数组、向量、列表或序列的形式实现的 现在我有一个返回布尔值的示例服务(这是PHP中的,但可以是任何服务器端语言): 结果将是: -> true -> boolean 我的问题是为什么允许将布尔值作为JSON返回。 它与JSON定义不冲突吗 产科加强生命支持 我还可以在我的服务中返回数字或字符串: <?

发件人:

JSON构建在两种结构上:

  • 名称/值对的集合。在各种语言中,这是作为对象、记录、结构、字典、哈希表、键控列表或关联数组实现的
  • 值的有序列表。在大多数语言中,这是以数组、向量、列表或序列的形式实现的
现在我有一个返回布尔值的示例服务(这是PHP中的,但可以是任何服务器端语言):

结果将是:

-> true
-> boolean
我的问题是为什么允许将布尔值作为JSON返回。 它与JSON定义不冲突吗


产科加强生命支持 我还可以在我的服务中返回数字字符串

<?php
header('Content-Type: application/json');
echo '2013';
exit;
对于字符串:

<?php
header('Content-Type: application/json');
echo '"What is going on?"';
exit;

正确的说法是,有效的JSON文本只能是对象或数组。2009年,我向道格拉斯·克罗克福德(Douglas Crockford)询问了这一点,他证实了这一点,并说“严格来说,这是对象数组,就像在RFC中一样。”

第2节中规定了这一点:

JSON文本是序列化的对象或数组

JSON-text = object / array
上列出的原始JSON语法根本没有说明这一点。它定义了所有JSON类型,但没有说明这些类型中的哪一种可以用作“JSON文本”——一个完整有效的JSON片段

这就是为什么我问道格这件事,他把我介绍给RFC。不幸的是,他没有按照我的建议更新json.org来澄清这一点

可能正是由于这种混淆,许多JSON库会很高兴地为独立的字符串、数字、布尔值等创建和解析(无效)JSON,即使这些不是真正有效的JSON

一些JSON解析器更严格。例如,拒绝JSON文本,例如
101
“abc”
、和
true
。它只接受对象或数组

JSON-text = object / array
如果您只是在自己的web应用程序中生成用于消费的JSON数据,那么这种区别可能并不重要。毕竟,
JSON.parse()

但如果您生成JSON供其他人使用,这一点很重要。在那里,你应该更严格地遵守标准

我建议即使在你自己的应用程序中也要遵循它,部分原因是它有一个实际的好处:通过发送一个对象而不是一个简单的字符串,你有一个内置的位置来添加更多的信息,如果你需要的话,可以在对象中添加额外的属性

沿着这些思路,当我定义JSON API时,我从不在最顶层使用数组。如果我拥有的是某种类型的项目数组,我仍然将其包装在一个对象中:

{
    "items": [
        ...
    ]
}
这部分是出于同样的原因:如果我以后想在响应中添加其他内容,那么将顶层设置为对象将使这一操作变得容易,而不会中断任何现有的客户端代码


也许更重要的是,还有一种可能。(我认为风险只会影响使用
eval()
函数来解析JSON,因此使用
JSON.parse()
是安全的,但我对此不是100%肯定。)

注意,Michael Geary的答案已经过时,因为2013年的rfc7158不再将JSON文本限制为数组或对象。目前的RFC说:

JSON文本是一个序列化的值。请注意,某些以前的 JSON规范将JSON文本约束为对象或 数组。仅生成对象或数组的实现,其中 所调用的JSON文本将是可互操作的,因为所有 实现将接受这些作为一致的JSON文本


它以json的形式返回以允许跨站点ajax请求如果您只能返回数组或对象,那么这些集合的内容是什么?您最终需要标量对象作为叶子。@Barmar-a“JSON文本”只能是一个数组或一个对象。但是,在该数组或对象中,您可以使用任何其他JSON数据类型。如果不重复,则相关:JSON数组的安全风险出现在CSRF上下文中,浏览器本身使用用户会话跨域解析通过脚本标记获取的JSON作为JS。也就是说,安全风险不在于脚本本身(假设它获取相同的原始数据),而在于数据的隐私。[或者应该说风险“是”…我认为浏览器现在已经消除了这些副作用。]@natevw-JSON数组漏洞与数据隐私无关,它意味着数据本身,作为JSON数组,也是有效的javascript,浏览器可能会执行实际代码而不是反序列化。为什么从不将JSON数组作为根数据返回,而是更喜欢使用带有“items”键的对象的主要原因。@AdrianCrețu请查看链接的讨论。因为JSON数组是有效的JavaScript,所以通过CORS旁路存在隐私风险。这个链接(来自另一个问答的评论)最直接地解释了:@AdrianCrețu…更不用说,如果你不信任服务器提供“安全”数组,你也不应该信任它和你对对象的“偏好”。问题在于跨域隐私(数组从您域上的用户会话泄漏到恶意会话),而不是不受信任的数据。@natevw-部分同意您的看法。但是,JSON对象本身不是有效的javascript代码,而数组是无效的。这有很大的区别,主要原因是微软自己将所有JSON代理数据包装在一些库中,以便嵌入JSON对象中,不管你是否相信:)
-> What is going on?
-> string
JSON-text = object / array
{
    "items": [
        ...
    ]
}