Application/json

**JSON**（**J**ava**S**cript **O**bject **N**otation, /ˈ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 用雙精度浮點數表示所有數值。
* 字串：以雙引號 `**""**` 括起來的零個或多個 Unicode 碼位。支援反斜槓開始的跳脫字元序列。
* 布林值：表示為 `true` 或者 `false`。
* 陣列：有序的零個或者多個值。每個值可以為任意類型。陣列使用方括號 `**[]**` 包裹。多個陣列元素之間用逗號 `**,**` 分隔，形如：`[value, value]`。
* 物件：若干無序的「鍵 - 值對」(key-value pairs)，其中鍵只能是字串。建議但不強制要求物件中的鍵是獨一無二的。物件以花括號 `**{}**` 包裹。多個鍵 - 值對之間使用逗號 `**,**` 分隔。鍵與值之間用冒號 `**:**` 分隔。
* 空值：值寫為 `null`

token（6 種標點符號、字串、數值、3 種字面量）之間可以存在有限的空白符並被忽略。四個特定字元被認為是空白符：空格符、水平制表符、回車字元、換行符。空白符不能出現在 token 內部（但空格符可以出現在字串內部）。JSON 標準不允許有位元組序遮罩，不提供注釋的句法。 一個有效的 JSON 文件的根節點必須是一個物件或一個陣列。

JSON 交換時必須編碼為 UTF-8。跳脫序列可以為：「\\」、「\"」、「\/」、「\b」、「\f」、「\n」、「\r」、「\t」，或 Unicode16 進位跳脫字元序列（\u 後面跟隨 4 位元 16 進位數字）。對於不在基本多文種平面上的碼位，必須用 UTF-16 代理對（surrogate pair）表示，例如對於 Emoji 字元 —— 喜極而泣的表情（U+1F602 😂 FACE WITH TEARS OF JOY）在 JSON 中應表示為：

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 使用在 JavaScript、Java、Node.js、C# 應用的情況比較多，PHP 等開發的 WEB 應用主要還是使用 XML。

### NoSQL 資料庫

相對於傳統的關係型資料庫，一些基於文件儲存的 NoSQL 非關係型資料庫選擇 JSON 作為其資料儲存格式，比較出名的產品有：MongoDB、CouchDB、RavenDB 等。

## 舉例

這種 JSON 格式也被不少遊戲（如 Minecraft）或應用軟體用來當作的部分資料儲存的格式：

## 安全問題

### 讀取 JSON

由於 JSON 是 JavaScript 的子集，所以一般都會使用 `eval()` 作為讀取資料的方式，如果是針對可靠的資料來源，在不支援原生 JSON 解析的瀏覽器上面這是最快速的方法。然而由於 eval 方法同樣可以執行任意的 JavaScript 代碼，因此當資料來源不可靠時則可能產生安全問題。如下面的例子，直接用 eval 執行時會跳轉：

其中一種防止不安全程式碼出現的解決辦法，是通過瀏覽器原生支援的 `JSON.parse(str)` 方法讀取 JSON 資料，目前已經得到大部分主流瀏覽器的支援（IE8+，Firefox 3.5+，Chrome4+/Safari4+，Opera10+），在不支援原生 JSON 物件的瀏覽器上面可以使用 `parseJSON` 方法進行讀取，`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 資料進行節點尋找和解析。

## 參考文獻

1. Apple 捷徑 （頁面存檔備份，存於網際網路檔案館）

## 參閱

* JSONP
* AJAX
* JavaScript
* YAML
* HOCON

## 外部連結

* （英文） JSON（頁面存檔備份，存於網際網路檔案館），關於 JSON 的規格、檔案，以及在其他語言實做的資訊
* JSON 中文說明 （頁面存檔備份，存於網際網路檔案館）
* （英文） RFC 4627，JSON 在 RFC 裡的規格
* JSON 格式化工具 (中文) （頁面存檔備份，存於網際網路檔案館）
* JSON 編輯器 （頁面存檔備份，存於網際網路檔案館）
* JSON 剖析器（頁面存檔備份，存於網際網路檔案館）
* JSON 到 CSV 轉換器 （頁面存檔備份，存於網際網路檔案館）
* Minecraft 指令─JSON 文字格式 （頁面存檔備份，存於網際網路檔案館）
* JSON 線上格式化工具