JSON

以 Javascript 为基础的一种轻量级的数据交换语言。

这是本页的一个历史版本,由Zisong chen留言 | 贡献2023年6月12日 (一) 08:06 安全問題:​ 新条目)编辑。这可能和当前版本存在着巨大的差异。

JSONJavaScript Object Notation, /ˈsən/)是由美國程式設計師道格拉斯·克羅克福特構想和設計的一種輕量級資料交換格式。其內容由屬性和值所組成,因此也有易於閱讀和處理的優勢。JSON是獨立於程式語言资料格式,其不僅是JavaScript的子集,也採用了C語言家族的習慣用法,目前也有許多程式語言都能夠將其解析和字串化,其廣泛使用的程度也使其成為通用的資料格式。

JSON
扩展名
.json
互联网媒体类型
application/json
类型代码英语Type codeTEXT
统一类型标识public.json
格式类型数据交换
扩展自JavaScript
标准RFC 7159, ECMA-404
网站json.org

簡介

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

JSON的基本数据类型:

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

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

JSON交换时必须编码为UTF-8[2]转义序列可以为:“\\”、“\"”、“\/”、“\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。

应用领域

元数据和架构

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使用在JavaScriptJavaNode.jsC#應用的情況比較多,PHP等開發的WEB應用主要還是使用XML

NoSQL数据库

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

举例

{
     "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":
                    {
                         "extra": "something"
                    }
               }
     },
     {
          "translate": "item.dirt.name",
          "color": "blue",
          "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方法进行读取[3]parseJSON採用解析器驗證讀入的程式碼是否真的是JSON程式碼,這樣就更安全。但由於這是用模擬的方式讀取,速度上會比eval()慢。

跨站存取問題

另外一個安全上的問題則是跨站請求偽造(Cross-site request forgery,簡稱CSRF或XSRF)。這個問題在Javascript中的狀況是,由於Javascript採用了稱為「沙盒」的機制,這種機制限制Javascript引擎僅能引入同一個站點的程式碼,因而某種程度上提高了安全性。

数据结构

JSON的基本数据类型有:

数字:带符号的十进制数,可以包含小数部分,可以使用指数 E 表示法,但不能包含 NaN 等非数字。 该格式不区分整数和浮点数。 JavaScript 对其所有数值使用 IEEE-754 双精度浮点格式(后来也支持 BigInt[4]),但其他实现 JSON 的语言可能对数字进行不同的编码。

字符串:零个或多个 Unicode 字符的序列。 字符串用双引号分隔并支持反斜杠转义语法。

布尔值:值 true 或 false

数组:零个或多个元素的有序列表,每个元素可以是任何类型。 数组使用带有逗号分隔元素的方括号表示法。

对象:名称-值对的集合,其中名称(也称为键)是字符串。 当前的 ECMA 标准声明:“JSON 语法不对用作名称的字符串施加任何限制,不要求名称字符串是唯一的,并且不对名称/值[5]对的顺序赋予任何意义。” 对象用大括号分隔,并使用逗号分隔每一对,而在每一对内,冒号“:”字符将键或名称与其值分隔开。

null:一个空值,使用 null 这个词

與其他格式的比較

XML

JSON與XML最大的不同在於XML是一個完整的標記語言,而JSON不是。這使得XML在程式判讀上需要比較多的功夫。主要的原因在於XML的設計理念與JSON不同。XML利用標記語言的特性提供了絕佳的延展性(如XPath),在数据存储,扩展及高级检索方面具备对JSON的优势,而JSON则由于比XML更加小巧,以及浏览器的内建快速解析支持,使得其更适用于网络数据传输领域。

MessagePack

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

格式化工具

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

參考文獻

  1. ^ MDN-JSON标准. [2021-10-30]. (原始内容存档于2022-04-03). 
  2. ^ The JavaScript Object Notation (JSON) Data Interchange Format. IETF. December 2017 [16 February 2018]. (原始内容存档于2021-01-20). 
  3. ^ JSON and Browser Security. [2007-07-14]. (原始内容存档于2020-07-16). 
  4. ^ BigInt - MDN Web Docs Glossary: Definitions of Web-related terms | MDN. developer.mozilla.org. 2023-06-08 [2023-06-12] (美国英语). 
  5. ^ ECMA-404. Ecma International. [2023-06-12] (美国英语). 
  1. Apple捷徑页面存档备份,存于互联网档案馆

參閱

外部連結