最小的有效 JSON 是多少?

IT技术 javascript json validation
2021-01-17 19:57:55

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

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

在撰写本文时,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 不是名词,所以“a JSON”是没有意义的。任何“JSON 值”都是“JSON 值”,但解析器通常需要该 RFC 中定义的“JSON 文本”。
2021-03-25 19:57:55
我不好我会删除我的答案然后
2021-03-25 19:57:55
@jmoreno:当然是第 2 节“JSON 文本是序列化对象或数组”中的引用。反对吗?JSON Lint 也不认为非数组或对象是有效的。关于字符串是否是有效的 JSON 文字没有争议;这结束了字符串本身是否有效。
2021-03-26 19:57:55
@jmoreno 你能澄清一下你的评论吗?你是说true, false, 还是null单独是一个有效的 JSON 文本?您能否引用一个来源,因为这与此处的大多数其他答案/评论相矛盾?
2021-03-30 19:57:55
@amdorra:你能更具体地说明你在哪里看到的吗?
2021-04-04 19:57:55

互联网上至少有四个文档可以被认为是 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 值”
  • PHP 函数json_decode是在 5.2.0 版本中引入的,只接受整个“JSON 文本”,但在 5.2.1 版本中被修改为接受任何“JSON 值”
  • json.loads根据本手册页上的示例 Python接受任何“JSON 值”
  • http://jsonlint.com 上的验证器需要完整的“JSON 文本”
  • Ruby JSON module将只接受完整的“JSON 文本”(至少根据本手册页上的注释

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

XML 比较可能不合适,因为没有可选的 XML 声明,XML 文档是完全有效的。请参阅w3.org/TR/xml/#sec-well-formed 上的 XML 建议
2021-04-01 19:57:55
@Gunther:吹毛求疵:<foo />是一个格式良好的XML 文档,但不是一个有效的文档(但同样适用于<?xml version="1.0" ?><foo />。)
2021-04-01 19:57:55
@Gunther 啊,是的,我忘记了它在技术上是可选的,尽管受到高度鼓励。
2021-04-09 19:57:55
@ruakh 有趣的是,这里的定义意味着 XML 只能对 DTD“有效”,这意味着很少有 XML 文档,因为 DTD 在实践中很少被编写和声明(与 XSD 或 RelaxNG 等模式定义格式相比) . 我正在检查,因为如果您可以在不引用外部架构的情况下对外部架构有效,那么对特定架构<foo /> 可能有效也可能无效,但这不是该标准规定的内容。
2021-04-09 19:57:55

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

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

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

我认为从这个方向接近答案比它澄清的更混乱:名称的起源与标准的细节无关,JavaScript 中可用的类型可能是 JSON 中类型的灵感,但没有要求他们匹配。json.org上的介绍清楚地表明:“JSON 是一种完全独立于语言的文本格式”
2021-03-25 19:57:55
@IMSoP 我完全同意。我将 Javascript 类型与 JSON 混合在一起,这是不正确的。我会更新我的答案。
2021-04-08 19:57:55

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("[]"); // []
你应该做 JSON.parse("\"string\"");
2021-03-26 19:57:55
虽然这是一个有用的参考,但它是特定 JSON 解析器(ECMAScript 标准中定义的)的规范,而不是格式本身。json.org明确声明 JSON 是“完全独立于语言的”,因此没有一个正确的解析器。
2021-03-28 19:57:55
JavaScript/ECMAScipt 是 JSON 的灵感来源,也是它的用户,但不是它的“家”。JSON 派生自(所有早期版本)ECMAScript 中的对象文字表示法,但并不完全相同。JSON.parse函数随后被添加到基于 Crockford 的语法和 RFC 的 ECMAScript 标准的更高版本中。
2021-04-03 19:57:55