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捷徑頁面存檔備份,存於網際網路檔案館

參閱

外部連結