type
status
date
slug
summary
tags
category
icon
password
😀
JSON(JavaScript对象表示法)已经成为现代数据交换的基石。它简洁、易读、跨语言,几乎无处不在。但你有没有想过,一个简单的字符串,比如 "hello",或者一个布尔值 true,能否单独构成一个完整的JSON文档? 对于许多开发者来说,JSON文档似乎总是以 {} 对象或 [] 数组开头。这并非偶然,而是JSON早期规范留下的“遗产”。然而,随着时间的推移,JSON的标准也在不断演进。今天,我们就来揭开JSON根元素支持单值(字符串、数字、布尔值、空值)的演变历程。

早期:严格的“对象或数组”规定 (RFC 4627)

在JSON的早期,特别是2006年7月发布的第一个重要IETF规范 RFC 4627 中,对JSON文档的结构有着严格的限制。这份规范明确规定,一个JSON文本(即整个文档)必须以一个对象 {} 或一个数组 [] 作为其最外层元素。
这意味着,虽然你可以在对象或数组内部使用字符串、数字、布尔值或空值,但它们不能单独作为整个JSON文档的根。例如,{"name": "Alice"}1 是有效的,但 "hello"123.45 如果单独出现,则被视为无效的JSON文本。这种限制在当时造成了一些与JavaScript原生处理方式的脱节,因为JavaScript本身允许任何值被序列化。

转折点:ECMA-404的隐含宽松 (2013年)

JSON的第一个正式标准化版本是 ECMA-404 第一版,于2013年10月发布。这份由Ecma国际(负责ECMAScript标准的机构)发布的文档,将JSON的地位从“信息性”RFC提升为正式标准。
尽管ECMA-404没有像RFC4627那样明确规定根元素必须是对象或数组,但它通过其语法定义隐含地允许了任何JSON值作为根。这与JSON的起源——ECMAScript——更加一致,因为ECMAScript本身就允许基本值作为有效构造。JSON.org网站也支持这一观点,列出了所有七种JSON类型(对象、数组、字符串、数字、truefalsenull)作为有效根元素。

明确的解放:RFC 7159 (2014年3月)

对“JSON何时支持单值”这个问题的最明确答案,在于 RFC 7159,发布于2014年3月。这份文档是IETF RFC系列中一个关键的里程碑,它正式且明确地移除了对JSON文本根元素的限制。
RFC 7159明确指出:“请注意,JSON的某些先前规范将JSON文本限制为对象或数组。”但它随后重新定义了JSON文本的语法为 JSON-text = ws value ws 。这里的 value 可以是:
  • 一个对象
  • 一个数组
  • 一个数字
  • 一个字符串
  • 三个字面量名称之一:falsenulltrue
这意味着,从2014年3月起,以下所有示例都成为完全有效的JSON文档:
  • "hello" (字符串)
  • true (布尔值)
  • 123.45 (数字)
  • null (空值)
RFC 7159废止了之前的RFC 4627,并成为了“JSON互联网使用的主要参考”。这巩固了新的、更宽松的定义在整个互联网范围内的地位。

稳定与成熟:当前标准 (RFC 8259 & ECMA-404 第二版)

JSON标准的演进并未止步。RFC8259(2017年12月)作为JSON的当前互联网标准(STD 90),废止了RFC7159。同时发布的还有 ECMA-404 第二版(2017年12月)。
这些当前标准在很大程度上保持了RFC 7159所建立的核心语法和定义,继续允许任何JSON值作为JSON文本的根元素。这标志着JSON定义进入了一个显著的稳定和成熟期,核心语法争议已基本解决。

互操作性考量:理论与实践的差距

尽管官方规范已经明确允许将单一基本值作为JSON文档的根,但在实际应用中,互操作性仍然是一个重要的考量。
许多严格按照RFC 4627开发的遗留系统和解析器可能尚未更新,因此它们可能只接受根元素为对象或数组的JSON文本 2。这可能导致在遇到以基本值作为根的JSON文本时,这些旧版解析器抛出错误。
因此,为了确保最大程度的互操作性,尤其是在面向公众的API或与未知客户端能力范围交互的系统中,通常建议传输根级别为对象或数组的JSON消息 2。这提供了一个一致、可扩展的结构,能够被新旧解析器普遍理解。

总结

JSON的根元素定义从最初的严格限制(仅对象或数组)到如今的灵活多变(任何JSON值),反映了其标准化过程中的实用主义演进。
  • 2006年7月 (RFC 4627): 严格限制为对象或数组。
  • 2013年10月 (ECMA-404 第一版): 隐含地允许任何JSON值作为根。
  • 2014年3月 (RFC 7159): 明确移除了限制,成为互联网主要参考。
  • 2017年12月 (RFC 8259 & ECMA-404 第二版): 保持了这种灵活性,并成为当前标准。
所以,下次当你看到一个简单的 "hello"true 作为JSON文档时,请记住,这在技术上是完全有效的。但在实际开发中,考虑到遗留系统的兼容性,以对象或数组作为根仍然是一种更稳健、更具互操作性的最佳实践。JSON的演变,正是技术标准适应实际需求、不断完善的生动写照。

参考文档

 
为什么割下的手指无法解锁现代手机?深入理解 TypeScript 的类型哲学:为何函数返回值需显式声明,而变量声明则倾向类型推断
Loading...