什麼是 JSON?

JSON(JavaScript Object Notation)是一種輕量級的資料交換格式,最初由 Douglas Crockford 在 2001 年提出。雖然名稱中包含 JavaScript,但 JSON 已經成為與語言無關的標準格式,幾乎所有主流程式語言都原生支援 JSON 的解析與生成。JSON 的正式規範定義在 ECMA-404 和 RFC 8259 中,這兩份文件確立了 JSON 作為全球通用資料交換格式的地位。

JSON 之所以受到廣泛採用,主要有三個原因:人類可讀性高機器解析效率好結構簡潔明瞭。與 XML 相比,JSON 不需要開閉標籤,檔案體積更小;與 CSV 相比,JSON 支援巢狀結構,能表達更複雜的資料關係;與 YAML 相比,JSON 的語法更嚴謹,不容易因為縮排錯誤導致解析失敗。

JSON 的主流應用場景

目前 JSON 最常見的應用場景包括:

  • RESTful API 的請求與回應格式:絕大多數現代 API(包含 GitHub API、Stripe API、OpenAI API)都使用 JSON 作為資料交換格式
  • 前後端之間的資料傳輸:前端 fetch()axios 發送的請求體幾乎都是 JSON
  • 設定檔:如 package.jsontsconfig.json.eslintrc.json、VS Code 的 settings.json
  • NoSQL 資料庫的儲存格式:MongoDB 使用 BSON(Binary JSON)、CouchDB 和 Firebase Firestore 直接儲存 JSON 文件
  • 跨系統的資料匯入匯出:許多 SaaS 產品支援 JSON 格式的資料匯出
  • GraphQL 回應格式:GraphQL API 的回應本身就是 JSON 結構

JSON 基本語法規則

JSON 的語法規則非常簡潔,只需要記住以下幾個核心原則。掌握這些規則是避免語法錯誤的基礎。

六大資料型別

JSON 支援六種資料型別,也僅限於這六種:

型別 範例 說明
字串 "Hello" 必須用雙引號包裹
數字 42, 3.14, -1, 1.5e10 整數或浮點數,支援科學記號,不加引號
布林值 true, false 小寫,不加引號
null null 表示空值,小寫
物件 {"key": "value"} 鍵值對,用大括號包裹
陣列 [1, 2, 3] 有序列表,用中括號包裹

需要特別注意的是,JSON 不支援 JavaScript 中的 undefinedNaNInfinityDate 物件、RegExp 物件或函式。這些型別如果需要序列化,必須先轉換為 JSON 支援的型別。

物件(Object)

物件是 JSON 最核心的結構,由鍵值對組成:

{
  "name": "張小明",
  "age": 28,
  "isStudent": false,
  "email": "ming@example.com",
  "address": null
}

重要規則:鍵(key)必須是雙引號字串,這是 JSON 和 JavaScript 物件最大的差異。在 JavaScript 中你可以寫 {name: "John"},但在 JSON 中這是非法的。

陣列(Array)

陣列用於儲存有序的值列表,陣列中的元素可以是任何 JSON 合法的資料型別:

{
  "fruits": ["蘋果", "香蕉", "芒果"],
  "scores": [95, 88, 72, 100],
  "mixed": [1, "hello", true, null, {"nested": "object"}]
}

巢狀結構:表達複雜資料關係

物件和陣列可以互相巢狀,表達複雜的資料關係。在實際的 API 開發中,巢狀結構幾乎無處不在:

{
  "company": "科技公司",
  "founded": 2020,
  "departments": [
    {
      "name": "工程部",
      "headcount": 15,
      "employees": [
        {
          "name": "王大明",
          "role": "Tech Lead",
          "skills": ["Python", "JavaScript", "SQL"],
          "projects": [
            {"name": "API Gateway", "status": "active"},
            {"name": "Auth Service", "status": "completed"}
          ]
        }
      ]
    },
    {
      "name": "設計部",
      "headcount": 8,
      "employees": [
        {
          "name": "李小華",
          "role": "Senior Designer",
          "skills": ["Figma", "Photoshop", "Illustrator"]
        }
      ]
    }
  ]
}

巢狀層級沒有規範上的限制,但實務上建議控制在 4-5 層以內,過深的巢狀會嚴重降低可讀性和維護性。

常見的 JSON 語法錯誤

即使是經驗豐富的開發者,也經常在 JSON 中犯下以下錯誤。使用 JSON 格式化工具 可以即時偵測並定位這些問題。

1. 使用單引號

// 錯誤
{'name': 'John'}

// 正確
{"name": "John"}

JSON 規範只允許雙引號,單引號在 JavaScript 和 Python 中合法,但在 JSON 中會導致解析失敗。這是從 JavaScript 物件直接複製到 JSON 時最容易犯的錯誤。

2. 結尾多餘的逗號(Trailing Comma)

// 錯誤
{
  "name": "John",
  "age": 30,
}

// 正確
{
  "name": "John",
  "age": 30
}

最後一個元素後面不能有逗號,這是最常見的手動編輯錯誤。JavaScript 和 TypeScript 允許 trailing comma,但 JSON 嚴格禁止。許多 IDE 的自動格式化功能可能會在 JavaScript 物件中加入 trailing comma,直接複製到 JSON 就會出錯。

3. 鍵沒有引號

// 錯誤
{name: "John", age: 30}

// 正確
{"name": "John", "age": 30}

所有的鍵都必須用雙引號包裹。這也是 JavaScript 物件與 JSON 的重要差異。

4. 使用註解

// 錯誤 — JSON 不支援註解
{
  "name": "John" // 使用者名稱
  /* 這也不行 */
}

標準 JSON 不支援任何形式的註解,包括 // 單行註解和 /* */ 多行註解。如果需要在設定檔中加註解,可以考慮使用 JSON5、JSONC(VS Code 的 settings.json 就是使用 JSONC 格式)或 YAML。

5. 使用 undefined、NaN 或 Infinity

// 錯誤
{"value": undefined, "score": NaN, "limit": Infinity}

// 正確
{"value": null, "score": 0, "limit": 999999}

JSON 只支援 null 來表示空值,不支援 JavaScript 的 undefinedNaNInfinity

6. 字串中未跳脫的特殊字元

// 錯誤 — 字串中有未跳脫的換行和引號
{"message": "他說 "你好"
然後離開了"}

// 正確
{"message": "他說 \"你好\"\n然後離開了"}

JSON 字串中的雙引號必須用 \" 跳脫,換行必須用 \n 表示。其他需要跳脫的字元包括:\\(反斜線)、\/(斜線)、\t(Tab)、\r(回車)、\uXXXX(Unicode)。

JSON 格式化的重要性

在實際開發中,API 回傳的 JSON 資料通常是壓縮格式(minified),也就是去除所有空白和換行的單行文字。例如:

{"users":[{"id":1,"name":"張三","email":"zhang@example.com","roles":["admin","editor"],"settings":{"theme":"dark","lang":"zh-TW"}},{"id":2,"name":"李四","email":"li@example.com","roles":["viewer"],"settings":{"theme":"light","lang":"en"}}]}

這種格式雖然節省傳輸頻寬(通常可減少 30-50% 的體積),但對人類閱讀極不友善。使用 JSON 格式化工具 進行 Pretty Print 後:

{
  "users": [
    {
      "id": 1,
      "name": "張三",
      "email": "zhang@example.com",
      "roles": ["admin", "editor"],
      "settings": {
        "theme": "dark",
        "lang": "zh-TW"
      }
    },
    {
      "id": 2,
      "name": "李四",
      "email": "li@example.com",
      "roles": ["viewer"],
      "settings": {
        "theme": "light",
        "lang": "en"
      }
    }
  ]
}

格式化的具體好處

  • 快速辨識巢狀層級:透過縮排一目了然
  • 容易發現缺少的逗號或括號:每一對大括號和中括號的對應關係清晰可見
  • 方便比對兩份 JSON 的差異:格式化後使用 diff 工具效果更佳
  • Debug API 回應時節省時間:快速定位問題欄位
  • 程式碼審查(Code Review)更高效:設定檔變更一目了然

實用的 JSON 工具

線上格式化工具

Super Tools 提供了免費的 JSON 格式化工具,支援以下功能:

  • 一鍵格式化:貼上壓縮的 JSON,自動美化排版,可選擇 2 格或 4 格縮排
  • 語法驗證:即時偵測語法錯誤並標示行號與位置
  • 壓縮功能:將格式化的 JSON 壓縮為單行,適合放進 API 請求
  • 複製匯出:一鍵複製結果到剪貼簿
  • 樹狀檢視:以樹狀結構瀏覽 JSON,方便查看大型資料

命令列工具 jq

如果你習慣在終端機操作,jq 是最推薦的 JSON 處理工具,被稱為「JSON 世界的 awk/sed」:

# 安裝 jq
brew install jq          # macOS
sudo apt install jq      # Ubuntu/Debian

# 格式化 JSON 檔案
cat data.json | jq '.'

# 提取特定欄位
cat data.json | jq '.users[0].name'

# 篩選陣列(找出年齡大於 25 的使用者)
cat data.json | jq '.users[] | select(.age > 25)'

# 只提取特定欄位(類似 SQL 的 SELECT)
cat data.json | jq '.users[] | {name, email}'

# 統計陣列長度
cat data.json | jq '.users | length'

# 搭配 curl 使用(格式化 API 回應)
curl -s https://api.example.com/users | jq '.'

jq 的表達式語法非常強大,可以進行篩選、轉換、聚合等操作,是後端開發者和 DevOps 工程師的必備工具。

Python 內建 JSON 工具

Python 內建的 json 模組已經足夠處理大多數場景:

# 命令列格式化
python3 -m json.tool < data.json

# 指定縮排
python3 -c "import json, sys; print(json.dumps(json.load(sys.stdin), indent=2, ensure_ascii=False))" < data.json

在 Python 程式中使用:

import json

# 解析 JSON 字串
data = json.loads('{"name": "張三", "age": 30}')

# 格式化輸出(縮排 2 格,保留中文)
pretty = json.dumps(data, indent=2, ensure_ascii=False)

# 讀取 JSON 檔案
with open('config.json', 'r', encoding='utf-8') as f:
    config = json.load(f)

# 寫入 JSON 檔案
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

JavaScript / Node.js 中的 JSON 處理

// 解析 JSON 字串
const data = JSON.parse('{"name": "John"}');

// 格式化輸出(縮排 2 格)
const pretty = JSON.stringify(data, null, 2);

// 使用 replacer 過濾特定欄位
const filtered = JSON.stringify(data, ['name', 'email'], 2);

// 使用 replacer 函式自訂序列化
const custom = JSON.stringify(data, (key, value) => {
  if (key === 'password') return undefined; // 移除密碼欄位
  return value;
}, 2);

JSON Schema 驗證

對於正式的 API 開發,手動檢查 JSON 格式遠遠不夠。JSON Schema 是一套標準化的驗證規範,能自動驗證 JSON 資料的結構和型別:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "roles": {
      "type": "array",
      "items": {"type": "string"},
      "minItems": 1
    }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}

JSON Schema 的實際用途

  • API 端點驗證:在伺服器端自動驗證請求格式,減少無效資料進入系統
  • 表單驗證:根據 Schema 自動生成前端表單驗證邏輯
  • 文件生成:Schema 本身就是最準確的 API 文件
  • Mock 資料生成:根據 Schema 自動生成測試用的假資料
  • IDE 自動補全:VS Code 等編輯器可根據 Schema 提供智慧提示

JSON 與其他格式的比較

在選擇資料格式時,了解各格式的特點有助於做出最佳決策:

特性 JSON XML YAML CSV
可讀性 最高
檔案體積 最小 最小
巢狀結構 支援 支援 支援 不支援
註解 不支援 支援 支援 不支援
Schema 驗證 JSON Schema XSD - -
瀏覽器原生支援 JSON.parse() DOMParser 需要函式庫 需要函式庫
主流用途 API、設定檔 企業系統 設定檔 資料匯出

API 開發中的 JSON 最佳實踐

一致的回應格式

為 API 定義統一的回應信封(envelope),讓前端開發者可以用一致的方式處理所有回應:

{
  "success": true,
  "data": {
    "users": [...]
  },
  "meta": {
    "total": 100,
    "page": 1,
    "limit": 20
  },
  "error": null
}

錯誤回應格式

{
  "success": false,
  "data": null,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Email 格式不正確",
    "details": [
      {"field": "email", "message": "必須是有效的 Email 地址"}
    ]
  }
}

命名慣例

  • 使用 camelCase(如 firstName):JavaScript 生態系的主流
  • 使用 snake_case(如 first_name):Python/Ruby 生態系的主流
  • 選定一種後全專案一致,不要混用

常見問題(FAQ)

Q1:JSON 和 JavaScript 物件有什麼差別?

JSON 是純文字格式,有嚴格的語法規範:鍵必須用雙引號、不支援函式、不支援 undefined、不支援註解、不允許 trailing comma。JavaScript 物件是程式語言中的資料結構,語法更寬鬆。兩者可以互相轉換,但不能直接互換使用。

Q2:JSON 檔案的副檔名是什麼?

標準副檔名是 .json,MIME 類型是 application/json。API 回應時應設定 Content-Type: application/json; charset=utf-8 標頭。

Q3:JSON 有大小限制嗎?

JSON 規範本身沒有大小限制。但實務上,各系統有各自的限制:大多數 Web 伺服器預設限制請求體在 1-10MB、MongoDB 單一文件上限 16MB、瀏覽器的 localStorage 通常限制在 5MB。處理大型 JSON 資料時,建議使用串流解析器(如 Python 的 ijson、Node.js 的 JSONStream)來避免記憶體溢位。

Q4:為什麼 JSON 不支援註解?

JSON 的設計者 Douglas Crockford 刻意移除了註解支援,原因是他觀察到人們經常在 JSON 設定檔的註解中加入解析指令,這違背了 JSON 作為純資料交換格式的設計初衷。如果你需要帶註解的設定檔,可以考慮使用 JSONC(JSON with Comments)、JSON5 或 YAML。

Q5:如何處理 JSON 中的日期時間?

JSON 沒有內建的日期型別。業界最佳實踐是使用 ISO 8601 格式的字串:"2026-03-28T14:30:00+08:00"。這種格式人類可讀、機器可解析,且包含時區資訊。避免使用 Unix timestamp(如 1711612200),因為它對人類完全不可讀。

總結

JSON 是現代 Web 開發不可或缺的資料格式。掌握正確的語法規則、熟悉常見錯誤模式、善用格式化與驗證工具,能大幅提升你的開發效率。無論你是前端工程師、後端開發者還是 DevOps 工程師,JSON 都是每天會接觸到的技術。

建議立即試試 Super Tools 的 JSON 格式化工具,貼上你手邊的 JSON 資料,親自體驗即時格式化、語法驗證與壓縮的便利性。如果你正在開發 API,也推薦搭配使用 Base64 編碼工具 處理二進位資料,或使用正則表達式測試工具驗證資料格式。

JSON 的安全性注意事項

在 API 開發中使用 JSON 時,有幾個安全性問題需要特別留意,這些問題在 JSON 格式化和解析過程中都可能出現。

JSON Injection 防範

當使用者輸入的內容被嵌入 JSON 回應中時,如果沒有適當的跳脫處理,可能導致 JSON 結構被篡改:

// 危險做法:直接拼接使用者輸入
const response = `{"message": "${userInput}"}`;

// 安全做法:使用 JSON.stringify 自動處理跳脫
const response = JSON.stringify({ message: userInput });

JSON.stringify 會自動處理字串中的雙引號、換行符、反斜線等特殊字元,是最可靠的 JSON 生成方式。永遠不要手動拼接 JSON 字串。

避免 JSON.parse 解析不受信任的資料時崩潰

在解析來自外部的 JSON 資料時,務必使用 try-catch 包裹,避免格式錯誤的 JSON 導致整個應用程式崩潰:

function safeJsonParse(text) {
  try {
    return { data: JSON.parse(text), error: null };
  } catch (e) {
    return { data: null, error: e.message };
  }
}

大數字精度問題

JSON 中的數字在 JavaScript 中會被解析為 IEEE 754 雙精度浮點數,當數字超過 Number.MAX_SAFE_INTEGER(9007199254740991)時會失去精度。這在處理資料庫 ID 或金融數據時特別危險:

{"id": 9007199254740993}

JavaScript 的 JSON.parse 會將此解析為 9007199254740992,末尾數字不正確。解決方案是將大數字以字串形式傳輸:

{"id": "9007199254740993"}

JSON 效能最佳化小技巧

減少 JSON 體積

在高流量的 API 中,JSON 回應的體積直接影響頻寬成本和回應速度。以下是幾個實用的優化技巧:

  • 移除不必要的欄位:API 只回傳前端需要的資料,避免把整個資料庫記錄都送出去
  • 縮短鍵名:在極端效能需求下,可以用簡短的鍵名(如 n 取代 name),搭配文件說明
  • 壓縮傳輸:啟用 gzip 或 brotli 壓縮,JSON 文字的壓縮率通常在 70-90%
  • 分頁設計:大量資料使用分頁(pagination)回傳,避免單次回應過大

這些 JSON 格式化與優化技巧在日常的 API 開發工作中非常實用。善用工具和遵循最佳實踐,能讓你的開發效率和程式碼品質都提升到更高的層次。