Skip to main content

RFC 8259 - JavaScript Object Notation (JSON) 数据交换格式

互联网工程任务组 (IETF)
请求评论: 8259
STD: 90
废止: 7159
类别: 标准跟踪

作者:
T. Bray (Textuality)

发布日期: 2017年12月


本备忘录的状态

这是一份互联网标准跟踪文档。

本文档是互联网工程任务组 (IETF, Internet Engineering Task Force) 的产品。它代表了IETF社区的共识。本文档已经过公开审查,并已被互联网工程指导组 (IESG, Internet Engineering Steering Group) 批准发布。有关互联网标准的更多信息,请参见RFC 7841的第2节。

有关本文档当前状态、任何勘误以及如何提供反馈的信息,请访问 https://www.rfc-editor.org/info/rfc8259。

版权声明

Copyright (c) 2017 IETF Trust and the persons identified as the document authors. All rights reserved.

本文档受BCP 78和IETF Trust关于IETF文档的法律规定 (https://trustee.ietf.org/license-info) 的约束,这些规定在本文档发布之日有效。请仔细阅读这些文档,因为它们描述了您对本文档的权利和限制。从本文档中提取的代码组件必须包含信托法律规定第4.e节中所述的简化BSD许可证文本,并且如简化BSD许可证中所述,不提供任何保证。

本文档可能包含2008年11月10日之前发布或公开的IETF文档或IETF贡献的材料。控制某些此类材料版权的人可能未授予IETF Trust允许在IETF标准流程之外修改此类材料的权利。未获得控制此类材料版权的人的充分许可,不得在IETF标准流程之外修改本文档,也不得在IETF标准流程之外创建本文档的衍生作品,除非为了将其格式化以供RFC编辑器发布或将其翻译成英语以外的语言。

摘要

JavaScript Object Notation (JSON,JavaScript对象表示法) 是一种轻量级、基于文本、语言无关的数据交换格式。它源自ECMAScript编程语言标准。JSON定义了一组小的格式规则,用于结构化数据的可移植表示。

本文档从ECMA-404中删除了JSON语法的不一致性,修复了规范错误,并提供了经验指导以增强互操作性。


目录


1. 引言 (Introduction)

JavaScript Object Notation (JSON) 是一种文本格式,用于结构化数据的序列化 (Serialization)。它源自JavaScript的对象字面量 (Object Literals),如ECMAScript编程语言标准第三版 [ECMA-262] 中所定义。

JSON可以表示四种原始类型 (布尔值、数字、字符串和null) 以及两种结构化类型 (对象和数组)。

字符串 (String) 是零个或多个Unicode字符 [UNICODE] 的序列。请注意,此引用是针对最新版本的Unicode,而不是特定的发行版。没有要求JSON解析器支持特定的Unicode版本或字符编码范围。

对象 (Object) 是零个或多个名称/值对 (Name/Value Pairs) 的无序集合,其中名称是字符串,值是字符串、数字、布尔值、null、对象或数组。

数组 (Array) 是零个或多个值的有序序列。

本文档中使用的术语"对象 (object)"和"数组 (array)"来自JavaScript的约定。

JSON的设计目标是使其最小化、可移植、文本化,并且是JavaScript的子集。

1.1 JSON与ECMA-404的关系

JSON语法是ECMA-404 [ECMA-404] ("JSON数据交换格式") 中语法的子集。此文档将本规范正确描述为与ECMA-404一致 (Consistent)。ECMA-404和本文档之间的预期一致性是,ECMA-404允许的所有文本也应该被本文档接受,但结构和语义要求更严格。如果ECMA-404与本文档不一致,则ECMA-404优先。

1.2 与RFC 7159的规范性差异

本文档用以下方式替换了RFC 7159 [RFC7159]:

  • 将JSON文本更改为只能是对象或数组 (之前的规范允许任何JSON值作为顶层文本)。
  • 删除了不一致的JSON语法定义,现在引用ECMA-404。
  • 强制规定必须使用UTF-8编码 (之前只是推荐)。
  • 添加了关于互操作性的指导。

2. JSON语法 (JSON Grammar)

JSON文本 (JSON Text) 是一个序列化的值 (Serialized Value)。请注意,RFC 7159之前的某些JSON文本不是JSON文本。

JSON值 (JSON Value) 必须 (MUST) 是对象、数组、数字或字符串,或者是以下三个字面量名称之一:

false
null
true

字面量名称必须 (MUST) 是小写。不允许使用其他字面量名称。

JSON-text = ws value ws
value = false / null / true / object / array / number / string
false = %x66.61.6c.73.65 ; false
null = %x6e.75.6c.6c ; null
true = %x74.72.75.65 ; true

允许在任何值的前后插入无关紧要的空白 (Whitespace)。

ws = *(
%x20 / ; Space
%x09 / ; Horizontal tab
%x0A / ; Line feed or New line
%x0D ) ; Carriage return

3. 值 (Values)

JSON值必须 (MUST) 是对象、数组、数字或字符串,或者是以下三个字面量名称之一: falsenulltrue


4. 对象 (Objects)

对象结构表示为一对大括号,包围零个或多个名称/值对 (或成员, Members)。名称是字符串。每个名称后跟一个冒号,将名称与值分隔开。单个逗号将一个值与后面的名称分隔开。对象内的名称应该 (SHOULD) 是唯一的。

object = begin-object [ member *( value-separator member ) ]
end-object

member = string name-separator value

begin-object = ws %x7B ws ; { left curly bracket
end-object = ws %x7D ws ; } right curly bracket
name-separator = ws %x3A ws ; : colon
value-separator = ws %x2C ws ; , comma

接收到对象的实现如果其成员名称不唯一,其行为是不可预测的。许多实现仅报告最后的名称/值对。其他实现会报告错误或无法解析对象,某些实现会报告所有的名称/值对,包括重复项。

JSON解析库在处理重复名称方面存在差异。某些实现在生成器 (Generators) 或解析器 (Parsers) 内检测重复名称,某些则不检测。要确保互操作性最大化,名称在对象内应该 (SHOULD) 是唯一的。


5. 数组 (Arrays)

数组结构表示为方括号,包围零个或多个值 (或元素, Elements)。元素由逗号分隔。

array = begin-array [ value *( value-separator value ) ] end-array

begin-array = ws %x5B ws ; [ left square bracket
end-array = ws %x5D ws ; ] right square bracket

6. 数字 (Numbers)

数字的表示类似于大多数编程语言中使用的表示。数字包含一个整数部分 (可能以减号作为前缀)、可选的小数部分和可选的指数部分。

不允许使用八进制和十六进制形式。

不允许前导零。

小数部分是小数点后跟一位或多位数字。

指数部分以字母E (大写或小写) 开头,后面可以跟加号或减号。E和可选符号后跟一位或多位数字。

不能表示为JSON数字序列的数值 (如无穷大 (Infinity) 和NaN) 不得 (MUST NOT) 使用。

number = [ minus ] int [ frac ] [ exp ]

decimal-point = %x2E ; .
digit1-9 = %x31-39 ; 1-9
e = %x65 / %x45 ; e E
exp = e [ minus / plus ] 1*DIGIT
frac = decimal-point 1*DIGIT
int = zero / ( digit1-9 *DIGIT )
minus = %x2D ; -
plus = %x2B ; +
zero = %x30 ; 0

本规范允许实现对可接受数字的范围和精度设置限制。由于软件实现JSON数字作为IEEE 754二进制64 (双精度, Double Precision) 数字是常见的 [IEEE754],因此这通常是良好的互操作性的情况。请注意,当此类软件用于读取JSON文本时,它可能会丢失某些数字的精度。

实施了任意精度算术的实现可能会期望通信它接受极大或极高精度的数字。接收JSON的实现可以 (MAY) 对其接受的数字的大小和精度设置限制,但必须 (MUST) 在IEEE 754二进制64双精度范围和精度内接受所有数字。


7. 字符串 (Strings)

字符串的表示类似于C语言家族编程语言中使用的约定。字符串以引号开始和结束。所有Unicode字符都可以放在引号内,但必须 (MUST) 转义的字符除外: 引号 (quotation mark)、反斜杠 (reverse solidus) 和控制字符 (U+0000到U+001F)。

有两个字符的转义序列表示可用于表示某些常见字符:

\"  引号 (quotation mark U+0022)
\\ 反斜杠 (reverse solidus U+005C)
\/ 斜杠 (solidus U+002F)
\b 退格 (backspace U+0008)
\f 换页 (form feed U+000C)
\n 换行 (line feed U+000A)
\r 回车 (carriage return U+000D)
\t 制表符 (tab U+0009)

因此,例如,仅包含单个反斜杠字符的字符串可以表示为 "\\"

或者,有一个六字符序列可以表示基本多语言平面 (BMP, Basic Multilingual Plane) 中的任何字符。序列的形式为 \u 后跟四个表示字符代码点的十六进制数字。十六进制字母A-F可以是大写或小写。因此,例如,仅包含单个反斜杠字符的字符串可以表示为 "\u005C"

要转义不在BMP中的字符,使用表示UTF-16代理对 (Surrogate Pair) 的十二字符序列。例如,仅包含G谱号字符 (U+1D11E) 的字符串可以表示为 "\uD834\uDD1E"

string = quotation-mark *char quotation-mark

char = unescaped /
escape (
%x22 / ; " quotation mark U+0022
%x5C / ; \ reverse solidus U+005C
%x2F / ; / solidus U+002F
%x62 / ; b backspace U+0008
%x66 / ; f form feed U+000C
%x6E / ; n line feed U+000A
%x72 / ; r carriage return U+000D
%x74 / ; t tab U+0009
%x75 4HEXDIG ) ; uXXXX U+XXXX

escape = %x5C ; \
quotation-mark = %x22 ; "
unescaped = %x20-21 / %x23-5B / %x5D-10FFFF

8. 字符串和字符问题 (String and Character Issues)

8.1 字符编码

JSON文本必须 (MUST) 使用UTF-8 [RFC3629] 编码。

实现不得 (MUST NOT) 在JSON文本的开头添加字节顺序标记 (BOM, Byte Order Mark, U+FEFF)。为了实现互操作性,解析JSON文本的实现可以 (MAY) 忽略开头的BOM,而不是将其视为错误。

8.2 Unicode字符

当引用控制字符的Unicode字符值时,本规范使用Unicode约定 "U+" 后跟十六进制字符代码点值。例如,"U+0022"表示引号字符。

8.3 字符串比较

软件实现通常通过检查它们的字节序列 (使用UTF-8编码表示形式) 来确定两个字符串是否相等,而不考虑Unicode标准化或区域设置。

JSON字符串比较也可以这样完成。


9. 解析器 (Parsers)

JSON解析器将JSON文本转换为另一种表示形式。JSON解析器必须 (MUST) 接受符合JSON语法的所有文本。JSON解析器可以 (MAY) 接受非JSON格式或扩展。

实现可能对JSON文本的大小设置限制,这些限制可能会强加给它。实现不得 (MUST NOT) 在结构深度、文本长度或数字值范围的能力上设置限制。


10. 生成器 (Generators)

JSON生成器 (Generator) 生成JSON文本。生成的文本必须 (MUST) 严格符合JSON语法。


11. IANA考虑 (IANA Considerations)

application/json媒体类型用于JSON文本。

Type name: application
Subtype name: json
Required parameters: n/a
Optional parameters: n/a
Encoding considerations: binary
Security considerations: See RFC 8259, Section 12
Interoperability considerations: Described in RFC 8259
Published specification: RFC 8259
Applications that use this media type:
JSON已被非常广泛地用作Web服务、配置文件、消息传递系统等的数据交换格式。
Fragment identifier considerations: n/a
Additional information:
Deprecated alias names for this type: n/a
Magic number(s): n/a
File extension(s): .json
Macintosh file type code(s): TEXT
Person & email address to contact for further information:
IESG <[email protected]>
Intended usage: COMMON
Restrictions on usage: none
Author: Douglas Crockford <[email protected]>
Change controller: IESG <[email protected]>

12. 安全考虑 (Security Considerations)

通常,在设计安全系统时,当接收到可能由敌对来源生成的任何数据时,需要特别小心。JSON是这类数据的常见格式。

JSON的一个众所周知的风险是,某些JSON文本在JavaScript解释器中的评估可能会导致安全漏洞的执行。通常,最安全的做法是使用特定的JSON解析器,而不是将JSON文本传递给JavaScript的 eval() 函数或类似机制。

大多数JSON库的实现者已经认识到JSON大小或嵌套深度可能被用于发起拒绝服务攻击 (DoS, Denial of Service)。实现应该防止此类攻击,例如通过设置最大数据大小或嵌套深度来防止滥用。

请参阅 [ECMA-404] 的第10节 "安全性"了解更多安全问题。


13. 示例 (Examples)

这是一个包含两个对象的JSON数组:

[
{
"precision": "zip",
"Latitude": 37.7668,
"Longitude": -122.3959,
"Address": "",
"City": "SAN FRANCISCO",
"State": "CA",
"Zip": "94107",
"Country": "US"
},
{
"precision": "zip",
"Latitude": 37.371991,
"Longitude": -122.026020,
"Address": "",
"City": "SUNNYVALE",
"State": "CA",
"Zip": "94085",
"Country": "US"
}
]

以下是三个仅包含值的小型JSON文本:

"Hello world!"
42
true

14. 参考文献 (References)

14.1 规范性参考

[ECMA-404] Ecma International, "The JSON Data Interchange Format", Standard ECMA-404, <http://www.ecma-international.org/publications/standards/Ecma-404.htm>.

[IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", IEEE 754.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <https://www.rfc-editor.org/info/rfc3629>.

[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[UNICODE] The Unicode Consortium, "The Unicode Standard", <http://www.unicode.org/versions/latest/>.

14.2 信息性参考

[ECMA-262] Ecma International, "ECMAScript Language Specification", Standard ECMA-262, Third Edition, December 1999, <http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf>.

[Err3607] RFC Errata, Erratum ID 3607, RFC 7159, <https://www.rfc-editor.org/errata/eid3607>.

[Err3915] RFC Errata, Erratum ID 3915, RFC 7159, <https://www.rfc-editor.org/errata/eid3915>.

[Err4264] RFC Errata, Erratum ID 4264, RFC 7159, <https://www.rfc-editor.org/errata/eid4264>.

[Err4336] RFC Errata, Erratum ID 4336, RFC 7159, <https://www.rfc-editor.org/errata/eid4336>.

[RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 2014, <https://www.rfc-editor.org/info/rfc7159>.


附录 A. RFC 7159的变更

本附录是非规范性的。

RFC 7159相对于其前身RFC 4627进行了许多改进。本规范进一步改进了RFC 7159:

  • 删除了对JSON文本的不一致定义 (之前定义为任意JSON值,但ABNF语法仅定义为对象或数组)。现在JSON文本必须 (MUST) 只是对象或数组。

  • 删除了重复的JSON语法定义,现在引用ECMA-404。

  • 规定了JSON文本必须 (MUST) 使用UTF-8编码 (RFC 7159只是推荐使用UTF-8,但没有要求)。

  • 添加了关于互操作性的更多指导,包括:

    • 对象成员名称应该唯一
    • 解析器应接受IEEE 754二进制64双精度范围和精度内的所有数字
    • 字符串比较应基于Unicode代码点

这些改进增强了不同JSON实现之间的互操作性。


致谢

RFC 7159由RFC 4627的原作者Douglas Crockford修订。感谢以下人员对本文档的贡献: Allen Wirfs-Brock, Adrian Farrell, Alexey Melnikov, Ben Campbell, Brian Carpenter, Carsten Bormann, Dan Romascanu, Dave Cridland, Francis Dupont, Jakob Schlyter, Joe Hildebrand, Kathleen Moriarty, Matthew Miller, Paul Hoffman, Pete Resnick, Richard Barnes, Stephen Farrell, Tero Kivinen, 以及所有参与[email protected]邮件列表的人。


作者地址

Tim Bray (editor)
Textuality
Email: [email protected]
URI: https://www.tbray.org/