我已经仔细阅读了 JSON 描述http://json.org/,但我不确定我是否知道这个简单问题的答案。哪些字符串是最小可能的有效 JSON?
"string"
字符串是有效的 JSON 吗?42
简单数字是有效的 JSON 吗?true
布尔值是有效的 JSON 吗?{}
空对象是有效的 JSON 吗?[]
空数组是有效的 JSON 吗?
我已经仔细阅读了 JSON 描述http://json.org/,但我不确定我是否知道这个简单问题的答案。哪些字符串是最小可能的有效 JSON?
"string"
字符串是有效的 JSON 吗?42
简单数字是有效的 JSON 吗?true
布尔值是有效的 JSON 吗?{}
空对象是有效的 JSON 吗?[]
空数组是有效的 JSON 吗?在撰写本文时,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 对象接受所有JSON 值(包括字符串、空值和数字),即使 JSON 对象在技术上符合 RFC 4627。
请注意,因此您可以通过JSON.stringify(5)
将符合标准的浏览器中的数字字符串化,这将被另一个符合 RFC4627 的解析器拒绝,但没有上面列出的特定例外。例如,Ruby似乎就是这样一个例子,它只接受对象和数组作为 root。另一方面,PHP专门添加了“它还会对标量类型和 NULL 进行编码和解码”的例外情况。
互联网上至少有四个文档可以被认为是 JSON 标准。引用的 RFC 都描述了 mime 类型application/json
。以下是每个人对顶级值的看法,以及是否允许在顶部使用对象或数组以外的任何内容:
RFC-4627:否。
JSON 文本是一个令牌序列。令牌集包括六个结构字符、字符串、数字和三个文字名称。
JSON 文本是序列化的对象或数组。
JSON 文本 = 对象/数组
请注意,RFC-4627 被标记为“信息性”而不是“提议的标准”,并且它已被RFC-7159废弃,而RFC-7159又被 RFC-8259 废弃。
RFC-8259:是的。
JSON 文本是一个令牌序列。令牌集包括六个结构字符、字符串、数字和三个文字名称。
JSON 文本是一个序列化的值。请注意,某些先前的 JSON 规范将 JSON 文本限制为对象或数组。仅生成需要 JSON 文本的对象或数组的实现将是可互操作的,因为所有实现都将接受这些作为一致的 JSON 文本。
JSON-text = ws 值 ws
RFC-8259 的日期为 2017 年 12 月,并标有“互联网标准”。
ECMA-262:是的。
JSON Syntactic Grammar 根据 JSON 词法语法定义的标记来定义有效的 JSON 文本。语法的目标符号是 JSONText。
语法 JSONText :
JSON 值
JSON 值:
JSONNullLiteral
JSONBooleanLiteral
JSON对象
JSON数组
JSON字符串
JSON 编号
ECMA-404:是的。
JSON 文本是由符合 JSON 值语法的 Unicode 代码点形成的令牌序列。这组标记包括六个结构标记、字符串、数字和三个文字名称标记。
根据RFC 4627 中的旧定义(在 2014 年 3 月被 RFC 7159 废弃),这些都是有效的“JSON 值”,但只有最后两个会构成完整的“JSON 文本”:
JSON 文本是序列化的对象或数组。
根据所使用的解析器,无论如何都可能接受单独的“JSON 值”。例如(坚持“JSON 值”与“JSON 文本”术语):
JSON.parse()
现在在现代浏览器中标准化的函数接受任何“JSON 值”json_decode
是在 5.2.0 版本中引入的,只接受整个“JSON 文本”,但在 5.2.1 版本中被修改为接受任何“JSON 值”json.loads
根据本手册页上的示例, Python接受任何“JSON 值”这种区别有点像“XML 文档”和“XML 片段”之间的区别,虽然从技术上讲<foo />
是格式良好的 XML 文档(最好写成<?xml version="1.0" ?><foo />
,但正如评论中指出的那样,<?xml
声明在技术上是可选的)。
JSON 代表 JavaScript 对象表示法。只有{}
和[]
定义JavaScript对象。其他示例是值文字。Javascript 中有用于处理这些值的对象类型,但表达式"string"
是文字值的源代码表示,而不是对象。
请记住,JSON 不是 Javascript。它是一种表示数据的符号。它具有非常简单和有限的结构。JSON 数据是使用{},:[]
字符结构化的。您只能在该结构中使用文字值。
服务器以对象描述或文字值进行响应是完全有效的。所有 JSON 解析器都应该处理只处理一个文字值,但只能处理一个值。JSON 一次只能表示一个对象。因此,对于要返回多个值的服务器,它必须将其构造为对象或数组。
ecma 规范可能对参考有用:
http://www.ecma-international.org/ecma-262/5.1/
parse 函数解析一个 JSON 文本(一个 JSON 格式的字符串)并生成一个 ECMAScript 值。JSON 格式是 ECMAScript 文字的受限形式。JSON 对象被实现为 ECMAScript 对象。JSON 数组实现为 ECMAScript 数组。JSON 字符串、数字、布尔值和 null 被实现为 ECMAScript 字符串、数字、布尔值和 null。JSON 使用比 WhiteSpace 更有限的空白字符集,并允许 Unicode 代码点 U+2028 和 U+2029 直接出现在 JSONString 文字中,而无需使用转义序列。解析过程与 11.1.4 和 11.1.5 类似,受 JSON 语法约束。
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("[]"); // []