JSON 格式化工具

JSON(JavaScript Object Notation, /ˈdʒeɪsən/)是由美国程序员道格拉斯·克罗克福特构想和设计的一种轻量级资料交换格式。其内容由属性和值所组成,因此也有易于阅读和处理的优势。JSON 是独立于编程语言的资料格式,其不仅是 JavaScript 的子集,也采用了 C 语言家族的习惯用法,目前也有许多编程语言都能够将其解析和字符串化,其广泛使用的程度也使其成为通用的资料格式。

简介

JSON 格式是 1999 年《JavaScript Programming Language, Standard ECMA-262 3rd Edition》的子集合,所以可以在 JavaScript 以 eval()函数(javascript 通过 eval()调用解析器)读入。不过这并不代表 JSON 无法使用于其他语言,事实上几乎所有与网络开发相关的语言都有 JSON 函式库。

JSON 的基本数据类型:

  • 数值:十进制数,不能有前导 0,可以为负数,可以有小数部分。还可以用 e 或者 E 表示指数部分。不能包含非数,如 NaN。不区分整数与浮点数。JavaScript 用双精度浮点数表示所有数值(后来也支持 BigInt[1])。
  • 字符串:以双引号""括起来的零个或多个 Unicode 码位。支持反斜杠开始的转义字符序列。
  • 布尔值:表示为 true 或者 false。
  • 数组:有序的零个或者多个值。每个值可以为任意类型。数组使用方括号[]包裹。多个数组元素之间用逗号,分隔,形如:[value, value]。
  • 物件:若干无序的“键-值对”(key-value pairs),其中键只能是字符串[2]。建议但不强制要求对象中的键是独一无二的。对象以花括号{}包裹。多个键-值对之间使用逗号,分隔。键与值之间用冒号:分隔。
  • 空值:值写为 null

token(6 种标点符号、字符串、数值、3 种字面量)之间可以存在有限的空白符并被忽略。四个特定字符被认为是空白符:空格符、水平制表符、回车符、换行符。空白符不能出现在 token 内部(但空格符可以出现在字符串内部)。JSON 标准不允许有字节序掩码,不提供注释的句法。 一个有效的 JSON 文档的根节点必须是一个对象或一个数组。

JSON 交换时必须编码为 UTF-8。[3]转义序列可以为:“\\”、“\"”、“\/”、“\b”、“\f”、“\n”、“\r”、“\t”,或 Unicode16 进制转义字符序列(\u 后面跟随 4 位 16 进制数字)。对于不在基本多文种平面上的码位,必须用 UTF-16 代理对(surrogate pair)表示,例如对于 Emoji 字符——喜极而泣的表情( U+1F602 😂 FACE WITH TEARS OF JOY)在 JSON 中应表示为:

{ "face": "😂" }

// or

{ "face": "\uD83D\uDE02" }

JSON 的格式描述可以参考 RFC 4627。

应用领域

Metadata 和架构

JSON 文本的官方媒体类型是双引号,这一点在大多数现代的安装中都采用了这种类型。由于传统原因,许多服务提供商、浏览器、服务器、Web 应用程序、库、框架和 API 也支持非官方的 MIME 类型 或内容类型。值得注意的例子包括谷歌搜索 API,雅虎,脸谱的 API,Lift,和 Dojo Toolkit。JSON 架构指定一种基于 JSON 的格式,用于定义用于验证、文档和交互控制的 JSON 数据的结构。它为给定应用程序所需的 JSON 数据以及如何修改该数据提供协定。JSON 架构基于 XML 架构(XSD)中的概念,但基于 JSON。与在 XSD 中一样,相同的序列化/反序列化工具可用于架构和数据,并且它是自描述的。它在 IETF 的互联网草案中指定,目前为 2020-12 年草案,于 2021 年 1 月 28 日发布。有几个验证器可用于不同的编程语言,每个验证器都有不同程度的一致性。标准文件扩展名为 .json。JSON 标准不支持对象引用,但存在基于 JSON 的对象引用的 IETF 草案标准。

WEB 开发

JSON 最开始被广泛的应用于 WEB 应用的开发。不过目前 JSON 使用在 JavaScript、Java、Node.js、C#应用的情况比较多,PHP 等开发的 WEB 应用主要还是使用 XML。

NoSQL 数据库

相对于传统的关系型数据库,一些基于文档存储的 NoSQL 非关系型数据库选择 JSON 作为其数据存储格式,比较出名的产品有:MongoDB、CouchDB、RavenDB 等。

举例

        {
          "firstName": "John",
          "lastName": "Smith",
          "sex": "male",
          "age": 25,
          "address": 
          {
            "streetAddress": "21 2nd Street",
            "city": "New York",
            "state": "NY",
            "postalCode": "10021"
          },
          "phoneNumber": 
          [
            {
              "type": "home",
              "number": "212 555-1234"
            },
            {
              "type": "fax",
              "number": "646 555-4567"
            }
          ]
        }
      

这种 JSON 格式也被不少游戏(如 Minecraft)或应用软件用来当作的部分数据存储的格式:

        [
          {
            "text": "This is the text",
            "color": "dark_red",
            "bold": true,
            "strikethough": true,
            "clickEvent":
            {
              "action": "open_url",
              "value": "zh.wikipedia.org"
            },
            "hoverEvent":
            {
              "action": "show_text",
              "value":
              {
                "text": "something"
              }
            }
          },
          {
            "translate": "item.dirt.name",
            "color": "blue",
            "bold": false,
            "italic": true
          }
        ]
      

安全问题

读取 JSON

由于 JSON 是 JavaScript 的子集,所以一般都会使用 eval()作为读取资料的方式,如果是针对可靠的数据来源,在不支持原生 JSON 解析的浏览器上面这是最快速的方法。然而由于 eval 方法同样可以执行任意的 JavaScript 代码,因此当数据来源不可靠时则可能产生安全问题。如下面的例子,直接用 eval 执行时会跳转:

var json= eval("{message:(function (){ window.location='http://zh.wikipedia.org/wiki/JSON#.E5.AE.89.E5.85.A8.E6.80.A7.E5.95.8F.E9.A1.8C'; })()}");

其中一种防止不安全代码出现的解决办法,是通过浏览器原生支持的 JSON.parse(str)方法读取 JSON 资料,目前已经得到大部分主流浏览器的支持(IE8+,Firefox 3.5+,Chrome4+/Safari4+,Opera10+),在不支持原生 JSON 对象的浏览器上面可以使用 parseJSON 方法进行读取[4],parseJSON 采用解析器验证读入的代码是否真的是 JSON 代码,这样就更安全。但由于这是用模拟的方式读取,速度上会比 eval()慢。

跨站访问问题

另外一个安全上的问题则是跨站请求伪造(Cross-site request forgery,简称 CSRF 或 XSRF)。这个问题在 Javascript 中的状况是,由于 Javascript 采用了称为“沙盒”的机制,这种机制限制 Javascript 引擎仅能引入同一个站点的代码,因而某种程度上提高了安全性。

与其他格式的比较

XML

JSON 与 XML 最大的不同在于 XML 是一个完整的标记语言,而 JSON 不是。这使得 XML 在程序判读上需要比较多的功夫。主要的原因在于 XML 的设计理念与 JSON 不同。XML 利用标记语言的特性提供了绝佳的延展性(如 XPath),在数据存储,扩展及高级检索方面具备对 JSON 的优势,而 JSON 则由于比 XML 更加小巧,以及浏览器的内建快速解析支持,使得其更适用于网络数据传输领域。

MessagePack

MessagePack 宣称比 JSON 更短小,快速。

格式化工具

JSON 格式取代了 XML 给网络传输带来了很大的便利,但是却没有了 XML 的一目了然,尤其是 JSON 数据很长的时候,会让人陷入繁琐复杂的数据节点查找中。开发者可以通过在线 JSON 格式化工具,来更方便的对 JSON 数据进行节点查找和解析。