214

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

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

8 回答 8

182

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

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

然而,ECMA-404 的引入改变了这一点,更新的建议可以在这里阅读。我还写了一篇关于这个问题的博客文章。


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

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

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

  • 剪断

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

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

于 2013-08-24T14:17:10.127 回答
45

Internet 上至少有四个文档可以被视为 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 语法语法根据 JSON 词汇语法定义的标记定义了有效的 JSON 文本。语法的目标符号是 JSONText。

语法 JSONText :

JSON值

JSON值:

JSONNullLiteral

JSONBooleanLiteral

JSON对象

JSON数组

JSON字符串

JSON数字

ECMA-404是的。

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

于 2014-03-12T18:55:33.777 回答
10

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

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

根据使用的解析器,可能会接受单独的“JSON 值”。例如(坚持“JSON 值”与“JSON 文本”术语):

  • JSON.parse()现在在现代浏览器中标准化的函数接受任何“JSON 值”
  • PHP 函数json_decode是在 5.2.0 版中引入的,只接受整个“JSON 文本”,但在 5.2.1 版中被修改为接受任何“JSON 值”
  • 根据本手册页上的示例, Pythonjson.loads接受任何“JSON 值”
  • http://jsonlint.com上的验证器需要完整的“JSON 文本”
  • Ruby JSON 模块将只接受完整的“JSON 文本”(至少根据本手册页上的评论)

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

于 2013-08-24T14:18:29.257 回答
5

JSON 代表 JavaScript 对象表示法。只定义一个{}Javascript[]对象。其他示例是值文字。Javascript 中有用于处理这些值的对象类型,但表达式"string"是字面值而不是对象的源代码表示。

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

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

于 2013-08-24T14:27:40.903 回答
4

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("[]"); // []
于 2013-08-24T14:19:25.853 回答
2

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

但是,官方RFC 4627声明:

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

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

于 2013-08-24T14:18:29.520 回答
0
var x;
JSON.stringify(x); // will output "{}"

所以你的答案是"{}"它表示一个空对象。

于 2013-08-24T14:50:46.150 回答
-1

只需按照json.org页面上给出的铁路图即可。[] 和 {} 是最小可能的有效 JSON 对象。所以答案是 [] 和 {}。

于 2013-08-24T16:26:12.283 回答