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

时间:2013-06-06 06:33:44

标签: javascript ajax json

来自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定义有冲突吗?


ALSO

此外,我可以在我的服务中返回数字字符串

<?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

2 个答案:

答案 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文本。