[RFC Home] [TEXT|PDF|HTML] [Tracker] [IPR] [Errata] [Info page]

INTERNET STANDARD
Errata Exist
Internet Engineering Task Force (IETF)                      T. Bray, Ed.
Request for Comments: 8259                                    Textuality
Obsoletes: 7159                                            December 2017
Category: Standards Track
ISSN: 2070-1721


     JavaScript 对象表示法(JSON)数据交换格式

摘要

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

   本文档消除了 JSON 其他规范中的不一致之处,修正了规范错误,并提供了基于实践的互操作性指导。

本备忘录状态

   本文档为互联网标准轨道文件。

   本文档由互联网工程任务组(IETF)编制。它代表了 IETF 社区的共识。该文档已接受公众评审,并由互联网工程指导组(IESG)批准发布。
   关于互联网标准的更多信息可参见RFC 7841 第 2 节。

   有关本文档当前状态、勘误以及如何反馈的更多信息,请访问
   https://www.rfc-editor.org/info/rfc8259Bray                         Standards Track                    [Page 1]


RFC 8259                          JSON                     December 2017


Copyright Notice

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

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (https://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.

   This document may contain material from IETF Documents or IETF
   Contributions published or made publicly available before November
   10, 2008.  The person(s) controlling the copyright in some of this
   material may not have granted the IETF Trust the right to allow
   modifications of such material outside the IETF Standards Process.
   Without obtaining an adequate license from the person(s) controlling
   the copyright in such materials, this document may not be modified
   outside the IETF Standards Process, and derivative works of it may
   not be created outside the IETF Standards Process, except to format
   it for publication as an RFC or to translate it into languages other
   than English.

























Bray                         Standards Track                    [Page 2]


RFC 8259                          JSON                     December 2017


目录

   1.  引言  . . . . . . . . . . . . . . . . . . . . . . . .   3
     1.1.  本文档使用的惯例 . . . . . . . . . . . . . . . .   4
     1.2.  JSON 的规范  . . . . . . . . . . . . . . . . . .   4
     1.3.  本次修订介绍 . . . . . . . . . . . . . . . . . .   5
   2.  JSON 语法  . . . . . . . . . . . . . . . . . . . . .   5
   3.  值  . . . . . . . . . . . . . . . . . . . . . . . . .   6
   4.  对象 . . . . . . . . . . . . . . . . . . . . . . . . .   6
   5.  数组  . . . . . . . . . . . . . . . . . . . . . . . .   7
   6.  数字 . . . . . . . . . . . . . . . . . . . . . . . . .   7
   7.  字符串 . . . . . . . . . . . . . . . . . . . . . . . .   8
   8.  字符串与字符问题 . . . . . . . . . . . . . . . . . .   9
     8.1.  字符编码  . . . . . . . . . . . . . . . . . . .   9
     8.2.  Unicode 字符  . . . . . . . . . . . . . . . . .  10
     8.3.  字符串比较 . . . . . . . . . . . . . . . . . .  10
   9.  解析器 . . . . . . . . . . . . . . . . . . . . . . .  10
   10.  生成器  . . . . . . . . . . . . . . . . . . . . . .  10
   11.  IANA 事项 . . . . . . . . . . . . . . . . . . . . .  11
   12.  安全性注意事项 . . . . . . . . . . . . . . . . . .  12
   13.  示例  . . . . . . . . . . . . . . . . . . . . . . .  12
   14.  参考文献  . . . . . . . . . . . . . . . . . . . . .  14
     14.1.  规范性引用 . . . . . . . . . . . . . . . . . .  14
     14.2.  信息性引用 . . . . . . . . . . . . . . . . . .  14
   附录 A.  RFC 7159 的变更  . . . . . . . . . . . . . . . .  16
   贡献者  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  16
   作者地址  . . . . . . . . . . . . . . . . . . . . . . . . . . .  16

1.  引言

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

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

   字符串是一系列零个或多个 Unicode 字符 [UNICODE]。
   请注意,此引用指向 Unicode 的最新版本,而非特定版本。未来 Unicode 规范的变化不应影响 JSON 的语法。

   对象是零个或多个名称/值对的无序集合,其中名称为字符串,值可以是字符串、数字、布尔值、null、对象或数组。

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



Bray                         Standards Track                    [Page 3]


RFC 8259                          JSON                     December 2017


      “对象”和“数组”这两个术语来自 JavaScript 的惯例。

   JSON 的设计目标是:结构简洁、可移植、基于文本,并且是 JavaScript 的一个子集。

1.1.  本文档中使用的惯例

   本文档中的关键词 "MUST"(必须)、"MUST NOT"(禁止)、"REQUIRED"(要求)、"SHALL"(应当)、"SHALL NOT"(不得)、"SHOULD"(应该)、"SHOULD NOT"(不应该)、"RECOMMENDED"(推荐)、"NOT RECOMMENDED"(不推荐)、"MAY"(可以)和 "OPTIONAL"(可选),应按照 BCP
   14 [RFC2119] [RFC8174] 中的说明进行解释,并且仅在这些词语如示例所示,全部为大写时才采用此解释。

   本文档中的语法规则应按照 [RFC5234] 中的说明进行解释。

1.2.  JSON 的规范

   本文档取代了 [RFC7159]。 [RFC7159] 替代了最初描述 JSON 并注册了媒体类型 "application/json" 的 [RFC4627]。

   JSON 也在 [ECMA-404] 中有描述。

   上一句对 ECMA-404 的引用是规范性的,这并不是说实现者需要查阅 ECMA-404 才能理解本文档,而是强调在所有相关规范的“JSON 文本”定义中没有不一致之处。不过需注意,ECMA-404 允许了一些本规范为最大限度的互操作性而建议规避的做法。

   两份文档的语法目标保持一致,虽然描述方式不同。如果发现文档间存在差异,ECMA 和 IETF 会协作更新两份文档。

   若发现任何一份文档有错误,应检查另一份文档有无类似错误;如果有,应尽可能予以修正。

   如果将来对任何一份文档进行修改,ECMA 和 IETF 会协作,确保两份文档在更改后依然保持一致。






Bray                         Standards Track                    [Page 4]


RFC 8259                          JSON                     December 2017


1.3.  本次修订介绍

   自从RFC 4627发布以来,JSON 被广泛应用于各类场景。实践中发现,虽然某些用法被规范所允许,但却引发了互操作性问题。

   此外,关于RFC 4627(见 RFC 勘误 IDs 607 [Err607] 和 3607 [Err3607])以及RFC 7159(见 RFC 勘误 IDs 3915 [Err3915]、4264 [Err4264]、4336 [Err4336] 和 4388 [Err4388])也有少量勘误报告。

   本文档的目标是修正这些勘误,消除与其他 JSON 规范之间的不一致,并强调可能导致互操作性问题的用法。

2.  JSON 语法

   JSON 文本由一系列记号(token)组成。记号的集合包括六个结构性字符、字符串、数字和三个字面量名称。

   JSON 文本是一个经过序列化的值。需要注意的是,以前的某些 JSON 规范曾限定 JSON 文本必须为对象或数组。如果生成的 JSON 文本仅包含对象或数组,那么在需要 JSON 文本的场合可以保证互操作性,因为所有实现都会接受这样的 JSON 文本作为合规内容。

      JSON-text = ws value ws

   以下是六个结构性字符:

      begin-array     = ws %x5B ws  ; [ 左中括号

      begin-object    = ws %x7B ws  ; { 左大括号

      end-array       = ws %x5D ws  ; ] 右中括号

      end-object      = ws %x7D ws  ; } 右大括号

      name-separator  = ws %x3A ws  ; : 冒号

      value-separator = ws %x2C ws  ; , 逗号










Bray                         Standards Track                    [Page 5]


RFC 8259                          JSON                     December 2017


   在六个结构性字符的前后允许有无关紧要的空白符。

      ws = *(
              %x20 /              ; 空格
              %x09 /              ; 水平制表符
              %x0A /              ; 换行
              %x0D )              ; 回车

3.  值

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

      false
      null
      true

   字面量名称必须小写。不允许其他字面量名称。

      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

4.  对象

   对象结构表示为一对大括号包围着零个或多个名称/值对(成员)。名称是字符串。
   每个名称后紧跟一个冒号,用于分隔名称和值。每个值之间用一个逗号分隔,下一个名称紧随其后。对象中的名称应是唯一的。

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

      member = string name-separator value

   名称全部唯一的对象具有良好的互操作性,所有接收该对象的软件实现会一致地解析名称-值映射。
   当对象中的名称不唯一时,接收此类对象的软件行为是不可预测的。许多实现只报告最后一个名称/值对。其他实现会报告错误或解析失败。



Bray                         Standards Track                    [Page 6]


RFC 8259                          JSON                     December 2017


   有些实现会返回整个对象中所有的名称/值对,包括重复的名称。

已观察到,不同的 JSON 解析库对于是否将对象成员顺序暴露给调用方软件存在差异。如果实现的行为不依赖于成员顺序,那么这些实现之间具有良好的互操作性,因为不会受到顺序差异的影响。

5.  数组

   数组结构使用方括号包围零个或多个值(元素)来表示。各元素之间用逗号分隔。

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

   数组中的值没有要求必须属于相同类型。

6.  数字

   数字的表示方式类似于大多数编程语言。数字采用十进制,由十进制数字表示。它包含一个可以带有可选负号的整数部分,后面可以有小数部分和/或指数部分。不允许前导零。

   小数部分由一个小数点后跟一个或多个数字组成。

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

   不能用下述语法表示的数值(如 Infinity 和 NaN)是不允许的。

      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



Bray                         Standards Track                    [Page 7]


RFC 8259                          JSON                     December 2017


      int = zero / ( digit1-9 *DIGIT )

      minus = %x2D               ; 负号 -

      plus = %x2B                ; 加号 +

      zero = %x30                ; 0

   本规范允许实现自行设定可接受数字的范围和精度限制。由于支持 IEEE 754 binary64(双精度)数字 [IEEE754] 的软件通常可用且广泛应用,
   因此如果实现不期望超出该类型数字的精度与范围,可以获得良好的互操作性,即:各实现会在预期的精度内对 JSON 数字进行近似。例如 1E400 或 3.141592653589793238462643383279 这样的 JSON 数字,
   可能会带来互操作性问题,因为它意味着生成该数字的软件预期接收方具备比常见环境更强的数字范围和精度处理能力。

   需要注意的是,如果采用此类软件,且数字为整数并且在 [-(2**53)+1, (2**53)-1] 范围内,则具有良好互操作性,各实现会准确认同其数值。

7.  字符串

   字符串的表示方式类似于 C 语言家族的惯例。字符串以引号开始和结束。所有的 Unicode 字符都可以放在引号之内,除必须转义的字符外:引号、反斜杠以及控制字符(U+0000 到 U+001F)。

   任何字符都可以被转义。如果字符在基本多文种平面(U+0000 到 U+FFFF)内,则可以用六字符序列表示:一个反斜杠,后跟小写字母 u,然后是四个十六进制数字,
   代表字符的码点。A 至 F 的十六进制字母可以为大写或小写。例如:仅包含一个反斜杠字符的字符串可以表示为 "\u005C"。

   作为替代,部分常用字符也有两字符转义序列。例如,仅包含一个反斜杠的字符串也可以更简洁地表示为 "\\"。




Bray                         Standards Track                    [Page 8]


RFC 8259                          JSON                     December 2017


   要转义不在基本多文种平面(Basic Multilingual Plane, BMP)中的扩展字符,需要用 12 个字符的序列来表示该字符,
   对应 UTF-16 代理项对的编码。例如,一个仅包含高音谱号字符(U+1D11E)的字符串可以表示为 "\uD834\uDD1E"。

      string = quotation-mark *char quotation-mark

      char = unescaped /
          escape (
              %x22 /          ; "    引号  U+0022
              %x5C /          ; \    反斜杠 U+005C
              %x2F /          ; /    斜杠   U+002F
              %x62 /          ; b    退格   U+0008
              %x66 /          ; f    换页   U+000C
              %x6E /          ; n    换行   U+000A
              %x72 /          ; r    回车   U+000D
              %x74 /          ; t    制表符 U+0009
              %x75 4HEXDIG )  ; uXXXX       U+XXXX

      escape = %x5C              ; \

      quotation-mark = %x22      ; "

      unescaped = %x20-21 / %x23-5B / %x5D-10FFFF

8.  字符串与字符问题

8.1.  字符编码

   在非封闭生态系统之间交换的 JSON 文本必须采用 UTF-8 编码 [RFC3629]。

   之前的 JSON 规范在传输 JSON 文本时对 UTF-8 的使用没有强制要求。然而,绝大多数基于 JSON 的软件实现都选择使用 UTF-8 编码,以至于只有这种编码方式才能实现互操作性。

   实现不得在通过网络传输的 JSON 文本开头添加字节顺序标记(U+FEFF)。为提高互操作性,解析 JSON 文本的实现可以忽略字节顺序标记的存在,而不是将其作为错误处理。







Bray                         Standards Track                    [Page 9]


RFC 8259                          JSON                     December 2017


8.2.  Unicode 字符

   当 JSON 文本中所有字符串(无论是否转义)都仅由 Unicode 字符组成时 [UNICODE],
   该 JSON 文本具有良好的互操作性,也就是说,所有能够解析它的软件实现,在对象和数组中的名称及字符串值的内容上会保持一致。

   然而,本规范中的 ABNF 允许成员名称和字符串值包含无法编码为 Unicode 字符的位序列;例如,"\uDEAD"(一个未配对的 UTF-16 代理项)。
   在实践中曾观察到这样的情况,比如某些库在截断 UTF-16 字符串时未检查是否拆分了代理对。收到包含此类值的 JSON 文本的软件行为是不可预测的;
   例如,不同实现可能返回字符串长度不同,甚至出现严重运行时异常。

8.3.  字符串比较

   软件实现通常需要对对象成员的名称进行相等性测试。将文本表示转换为 Unicode 码元序列后,再逐码元进行数值比较的实现,
   具有良好的互操作性,也就是说,各种实现对于两个字符串是否相等会一致。例如,对于未转换转义字符就直接进行比较的实现,"a\\b" 和 "a\u005Cb" 可能会被错误地判定为不相等。

9.  解析器

   JSON 解析器会将 JSON 文本转换为其他表示形式。JSON 解析器必须接受所有符合 JSON 语法的文本。JSON 解析器可以接受非 JSON 形式或扩展内容。

   实现可以设置其可接受文本的大小限制。实现可以设置嵌套的最大深度限制。实现可以对数字的范围与精度设置限制。实现可以限制字符串的长度及字符内容。

10.  生成器

   JSON 生成器负责生成 JSON 文本。生成的文本必须严格符合 JSON 语法。





Bray                         Standards Track                   [Page 10]


RFC 8259                          JSON                     December 2017


11.  IANA 注意事项

   JSON 文本的媒体类型为 application/json。

   类型名称: application

   子类型名称: json

   必需参数: 不适用

   可选参数: 不适用

   编码注意事项: 二进制

   安全性注意事项: 参见 RFC 8259,第 12 节

   互操作性注意事项: 见 RFC 8259 描述

   发布规范: RFC 8259

   使用该媒体类型的应用:
      JSON 已被用于在以下编程语言编写的应用程序之间交换数据:ActionScript、C、C#、Clojure、ColdFusion、Common Lisp、E、Erlang、Go、Java、JavaScript、Lua、Objective CAML、Perl、PHP、Python、Rebol、Ruby、Scala 和 Scheme。

   附加信息:
      魔数(Magic number):不适用
      文件扩展名:.json
      Macintosh 文件类型代码:TEXT

   进一步信息联系人及邮箱:
      IESG
      <iesg@ietf.org>

   预期用途: 通用(COMMON)

   使用限制: 无

   作者:
      Douglas Crockford
      <douglas@crockford.com>

   变更控制者:
      IESG
      <iesg@ietf.org>




Bray                         Standards Track                   [Page 11]


RFC 8259                          JSON                     December 2017


   注意:本注册未定义 "charset" 参数。添加该参数对兼容的接收方实际上没有影响。

12.  安全性注意事项

   通常情况下,脚本语言存在安全性问题。JSON 是 JavaScript 的一个子集,但不包括赋值和调用。

   由于 JSON 的语法借鉴自 JavaScript,可以使用该语言的 "eval()" 函数来解析大多数 JSON 文本(但不是全部;某些字符如 U+2028 行分隔符和 U+2029 段分隔符在 JSON 中合法,
   但在 JavaScript 中不合法)。这通常构成不可接受的安全风险,因为文本可能包含可执行代码以及数据声明。
   同样的安全考虑也适用于在任何其他将 JSON 文本语法与该语言一致的编程语言中使用类似 eval() 的函数。

13.  示例

   以下是一个 JSON 对象:

      {
        "Image": {
            "Width":  800,
            "Height": 600,
            "Title":  "View from 15th Floor",
            "Thumbnail": {
                "Url":    "http://www.example.com/image/481989943",
                "Height": 125,
                "Width":  100
            },
            "Animated" : false,
            "IDs": [116, 943, 234, 38793]
          }
      }

   其中的 Image 成员是一个对象,其 Thumbnail 成员是对象,IDs 成员是一个数字数组。












Bray                         Standards Track                   [Page 12]


RFC 8259                          JSON                     December 2017


   这是一个包含两个对象的 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



















Bray                         Standards Track                   [Page 13]


RFC 8259                          JSON                     December 2017


14.  参考文献

14.1.  标准性引用

   [ECMA-404] Ecma International, "JSON 数据交换格式(The JSON Data Interchange Format)",
              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., "用于在RFC中指示需求级别的关键字(Key words for use in RFCs to Indicate Requirement Levels)", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, 1997年3月,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC3629]  Yergeau, F., "UTF-8,一种 ISO 10646 的变换格式(UTF-8, a transformation format of ISO 10646)", STD 63, RFC 3629, DOI 10.17487/RFC3629, 2003年11月,
              <https://www.rfc-editor.org/info/rfc3629>.

   [RFC5234]  Crocker, D., 编辑 和 P. Overell, "用于语法规范的扩展BNF(Augmented BNF for Syntax Specifications: ABNF)", STD 68, RFC 5234,
              DOI 10.17487/RFC5234, 2008年1月,
              <https://www.rfc-editor.org/info/rfc5234>.

   [RFC8174]  Leiba, B., "RFC 2119 关键字大小写不明确问题(Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words)", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              2017年5月, <https://www.rfc-editor.org/info/rfc8174>.

   [UNICODE]  Unicode 联盟, "Unicode 标准",
              <http://www.unicode.org/versions/latest/>.

14.2.  信息性引用

   [ECMA-262] Ecma International, "ECMAScript 语言规范(ECMAScript Language Specification)",
              ECMA-262 标准,第三版,1999年12月,
              <http://www.ecma-international.org/publications/files/
              ECMA-ST-ARCH/
              ECMA-262,%203rd%20edition,%20December%201999.pdf>.

   [Err3607]  RFC 勘误,勘误号 3607, RFC 4627,
              <https://www.rfc-editor.org/errata/eid3607>.

   [Err3915]  RFC 勘误,勘误号 3915, RFC 7159,
              <https://www.rfc-editor.org/errata/eid3915>.





Bray                         Standards Track                   [Page 14]


RFC 8259                          JSON                     December 2017


   [Err4264]  RFC 勘误,勘误编号 4264,RFC 7159,
              <https://www.rfc-editor.org/errata/eid4264>。

   [Err4336]  RFC 勘误,勘误编号 4336,RFC 7159,
              <https://www.rfc-editor.org/errata/eid4336>。

   [Err4388]  RFC 勘误,勘误编号 4388,RFC 7159,
              <https://www.rfc-editor.org/errata/eid4388>。

   [Err607]   RFC 勘误,勘误编号 607,RFC 4627,
              <https://www.rfc-editor.org/errata/eid607>。

   [RFC4627]  Crockford, D., "JavaScript 对象表示法 (JSON) 的 application/json 媒体类型",RFC 4627,
              DOI 10.17487/RFC4627,2006年7月,
              <https://www.rfc-editor.org/info/rfc4627>。

   [RFC7159]  Bray, T., 编辑, "JavaScript 对象表示法 (JSON) 数据交换格式",RFC 7159,DOI 10.17487/RFC7159,2014年3月,
              <https://www.rfc-editor.org/info/rfc7159>。






























Bray                         Standards Track                   [Page 15]


RFC 8259                          JSON                     December 2017


附录 A.  与 RFC 7159 的差异

   本节列出了本文件与RFC 7159文本之间的变更。

   o  第 1.2 节已更新,反映 JSON 规范从 ECMA-262 中移除,将 ECMA-404 设为规范性引用,并解释了“规范性”一词的特定含义。

   o  第 1.3 节已更新,反映了针对RFC 7159而非RFC 4627提出的勘误。

   o  第 8.1 节修改为要求网络传输时必须使用 UTF-8。

   o  第 12 节已更新,更详细地描述了使用 ECMAScript "eval()" 函数带来的安全风险。

   o  第 14.1 节已更新,将 ECMA-404 纳入规范性引用。

   o  第 14.2 节已更新,移除了 ECMA-404,更新了 ECMA-262 的版本并刷新了勘误列表。

贡献者

   RFC 4627 由 Douglas Crockford 撰写。本文档是在该文件基础上进行少量修改而成,因此这里绝大部分文本归功于他。

作者地址

   Tim Bray(编辑)
   Textuality

   电子邮箱:tbray@textuality.com














Bray                         Standards Track                   [Page 16]