最低有效JSON是多少?


173

我已经仔细阅读了JSON描述http://json.org/,但是我不确定我是否知道简单问题的答案。最小可能的有效JSON是什么字符串?

  • "string" 字符串是有效的JSON吗?
  • 42 简单数字是有效的JSON吗?
  • true 布尔值是有效的JSON吗?
  • {} 空对象是有效的JSON吗?
  • [] 空数组是有效的JSON吗?

12
jsonlint.com上进行测试,最后两个有效,而其他两个则无效。
ironcito

1
一些JSON解析器期望使用数组或对象。他们抱怨只是​​一个数字或一个字符串。
akonsu

3
到目前为止,这些有效
布赖恩·科拉维托


简短答案-{}
Tukaram Bhosale

Answers:


155

在撰写本文时,JSON仅在RFC4627中进行了描述。它(在“ 2”开头)将JSON文本描述为序列化的对象或数组。

这意味着在符合该标准的解析器和字符串化器中,只有 {}并且[]是有效的完整JSON字符串。

但是,ECMA-404的引入改变了这一点,更新的建议可以在此处阅读。我也写了一篇关于这个问题的博客文章


然而,为了进一步混淆该问题,Web浏览器中可用的JSON对象(例如JSON.parse()JSON.stringify()在ES5中进行了标准化,并且明确定义了可接受的JSON文本,如下所示:

本规范中使用的JSON交换格式与RFC 4627完全相同,但有两个例外:

  • ECMAScript JSON语法的顶级JSONText生成可以由任何JSONValue组成,而不是被RFC 4627指定为JSONObject或JSONArray。

  • 抢断

这意味着即使JSON对象在技术上遵循RFC 4627,JSON对象也可以接受所有 JSON值(包括字符串,空值和数字)。

请注意,因此您可以通过JSON.stringify(5),在符合标准的浏览器中对数字进行字符串化,该数字将被另一个遵循RFC4627,但没有上面列出的特定异常的解析器拒绝。例如,Ruby 似乎就是这样一个例子,它接受对象和数组作为root。另一方面,PHP 特别添加了一个例外,即“它还将对标量类型和NULL进行编码和解码”。


@amdorra:请问您在哪里看到的更具体?
马特

5
JSON不是名词,因此“ JSON”是没有意义的。任何“ JSON值”都是“ JSON值”,但是解析器通常期望该RFC中定义的“ JSON文本”。
IMSoP 2013年

2
我不好,我会删除我的答案
amdorra

1
@jmoreno您能否澄清您的评论?你说truefalse或者null单纯是一个有效的JSON文本?您能否引用一个消息来源,因为这与此处的其他大多数答案/评论相矛盾?
劳伦斯·约翰斯顿

2
@jmoreno:当然,第2节“ JSON文本是序列化的对象或数组”中的引号。反对吗?JSON Lint也不认为非数组或对象有效。对于字符串是否是有效的JSON文字,没有争议。这是关于字符串本身是否有效的问题。
马特

42

互联网上至少有四个文档可以视为JSON标准。所引用的RFC都描述了mime类型application/json。关于顶级值,以及在顶部是否允许除对象或数组之外的任何其他内容,这是每个人都必须说的:

RFC-4627

JSON文本是令牌序列。令牌集包括六个结构字符,字符串,数字和三个文字名称。

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

JSON文本=对象/数组

请注意,RFC-4627被标记为“信息性”,而不是“建议的标准”,并且RFC-7159已将其废弃,而RFC-8259又将其废弃。

RFC-8259是。

JSON文本是令牌序列。令牌集包括六个结构字符,字符串,数字和三个文字名称。

JSON文本是序列化的值。请注意,某些先前的JSON规范将JSON文本限制为对象或数组。从所有实现都将它们接受为符合JSON文本的意义上说,仅生成需要调用JSON文本的对象或数组的实现将可以互操作。

JSON文本= ws值ws

RFC-8259的日期为2017年12月,并标记为“ INTERNET STANDARD”。

ECMA-262是的。

JSON语法语法根据JSON词汇语法定义的标记定义了有效的JSON文本。语法的目标符号是JSONText。

语法JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404是。

JSON文本是由符合JSON值语法的Unicode代码点形成的令牌序列。令牌集包括六个结构令牌,字符串,数字和三个文字名称令牌。


10

根据RFC 4627中的旧定义(2014年3月被RFC 7159淘汰),这些都是有效的“ JSON值”,但只有最后两个会构成完整的“ JSON文本”:

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

根据所使用的解析器,无论如何都可以接受单独的“ JSON值”。例如(坚持“ JSON值”和“ JSON文本”术语):

  • JSON.parse()现在在现代浏览器中标准化的功能可以接受任何“ JSON值”
  • PHP函数json_decode在5.2.0版中引入,仅接受完整的“ JSON文本”,但在5.2.1版中进行了修改,以接受任何“ JSON值”
  • json.loads根据本手册页上的示例 Python 接受任何“ JSON值”
  • http://jsonlint.com上的验证程序需要完整的“ JSON文本”
  • Ruby JSON模块将仅接受完整的“ JSON文本”(至少根据本手册页上的注释)

区别有点像“ XML文档”和“ XML片段”之间的区别,尽管从技术上讲<foo />是格式良好的XML文档(最好写成<?xml version="1.0" ?><foo />,但正如注释中指出的那样,<?xml声明在技术上是可选的)。


XML比较可能不合适,因为没有可选的XML声明,XML文档完全有效。请参阅w3.org/TR/xml/#sec-well-formed中
Gunther

@Gunther啊,是的,我忘记了它在技术上是可选的,尽管受到强烈鼓励。
IMSoP

@Gunther:nitpick:<foo />格式正确的 XML文档,但不是有效的 XML文档。(但也是如此<?xml version="1.0" ?><foo />。)
ruakh

@ruakh有趣的是,这里的定义暗含XML对DTD只能是“有效的”,这意味着很少有XML文档,因为在实践中很少编写和声明DTD(与诸如XSD或RelaxNG之类的模式定义格式相比) 。我正在检查,因为如果您可以在不引用外部架构的情况下对它有效,那么对特定架构<foo /> 可能是有效的,也可能不是,但这不是该标准所规定的。
IMSoP

4

ecma规范可能对参考有用:

http://www.ecma-international.org/ecma-262/5.1/

parse函数解析JSON文本(JSON格式的String)并生成ECMAScript值。JSON格式是ECMAScript文字的一种受限制形式。JSON对象被实现为ECMAScript对象。JSON数组被实现为ECMAScript数组。JSON字符串,数字,布尔值和null被实现为ECMAScript字符串,数字,布尔值和null。JSON使用的空白字符集比WhiteSpace少得多,并且允许Unicode代码点U + 2028和U + 2029直接出现在JSONString文字中,而无需使用转义序列。解析过程类似于JSON语法所限制的11.1.4和11.1.5。

JSON.parse("string"); // SyntaxError: Unexpected token s
JSON.parse(43); // 43
JSON.parse("43"); // 43
JSON.parse(true); // true
JSON.parse("true"); // true
JSON.parse(false);
JSON.parse("false");
JSON.parse("trueee"); // SyntaxError: Unexpected token e
JSON.parse("{}"); // {}
JSON.parse("[]"); // []

4
虽然是有用的参考,但这是特定JSON解析器(在ECMAScript标准中定义的解析器)的规范,而不是格式本身。json.org明确声明JSON是“完全独立于语言的”,因此没有一个正确的解析器。
IMSoP

1
JavaScript / ECMAScipt是​​JSON的灵感来源,并且是它的用户,而不是它的“家”。JSON是从ECMAScript(所有早期版本)中的对象文字表示法派生的,但与它并不相同。JSON.parse然后基于Crockford的语法和RFC 将功能添加到ECMAScript标准的更高版本中。
IMSoP 2013年

4
您应该做JSON.parse("\"string\"");
ericbn

4

JSON代表JavaScript对象符号。只有{}[]定义JavaScript对象。其他示例是值文字。Javascript中有一些对象类型可以使用这些值,但是表达式"string"是文字值的源代码表示形式,而不是对象。

请记住,JSON不是Javascript。它是表示数据的符号。它具有非常简单和有限的结构。JSON数据使用{},:[]字符进行结构化。您只能在该结构内使用文字值。

服务器使用对象描述或文字值进行响应是完全有效的。所有JSON解析器都应处理仅处理一个文字值,但仅处理一个值的句柄。JSON一次只能代表一个对象。因此,要使服务器返回多个值,就必须将其构造为对象或数组。


1
我认为,从这个方向解决问题的方法比澄清的要多:名称的起源与标准的细节无关,JavaScript中可用的类型可能是JSON中类型的灵感,但没有要求他们匹配。json.org上的简介明确了这一点:“ JSON是一种完全独立于语言的文本格式”
IMSoP 2013年

@IMSoP我完全同意。我将Javascript类型与JSON混合在一起,这是不正确的。我将更新我的答案。
Reactgular

2

是的,是的,是的,是的,是的。它们都是有效的JSON值文字。

但是,正式的RFC 4627声明:

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

因此,整个“文件”应该由一个对象或数组组成,作为最外层结构,当然可以为空。但是,许多JSON解析器也接受原始值作为输入。



-2

只需遵循json.org页面上给出的铁路图即可。[]和{}是最小的有效JSON对象。因此答案是[]和{}。


3
这不是FSM,而是语法。而且它似乎并没有表明哪个生产是开始规则。如果开始的规则是arrayobject你是对的,但它是合理的期望value是开始。

不过对我来说看起来很简单。道格拉斯·克罗克福德(Douglas Crockford)称它们为“我们”,我们总是从左开始,然后沿右轨道前进。最小的轨道给出最小的有效JSON。
Hrishi

2
这不是您对我反对的任何特定语法规则的解释,而是您选择了两个规则,并假设一个规则只能从那些规则开始,而不能从其他规则开始。如果您查看values规则(而不是arrayobject规则)(或除此之外),那么独立的数字和字符串就是有效的JSON文档。

-1。首先,正如@delnan所指出的那样,json.org的图中没有任何内容表明完整的JSON文本必须是对象或数组。您已经任意选择了这两个,而不是基于json.org上的任何内容。其次,仔细研究术语:[],尽管在对此有意见的每一个规范下都有有效的JSON文本,但它不是“有效的JSON对象”,因为它不是JSON对象。JSON中的“对象”专门指代{}表示法。JSON数组不是JSON对象。
Mark Amery 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.