JSON 最佳实践:格式化、验证与解析

· 12分钟阅读

目录

JSON 基础

JSON(JavaScript Object Notation)是网络上使用最广泛的数据交换格式。它具有人类可读性、语言独立性,并且几乎被所有编程语言支持。理解 JSON 最佳实践对于构建可靠的 API、配置文件和数据管道至关重要。

JSON 最初源自 JavaScript,但现已成为通用标准。其简洁性和灵活性使其非常适合在服务器和 Web 应用程序之间传输数据、存储配置设置以及记录 API 响应。

核心数据类型

JSON 支持恰好六种数据类型。理解这些限制对于正确的 JSON 设计至关重要:

{
  "string": "Hello, World!",
  "number": 42,
  "decimal": 3.14,
  "boolean": true,
  "null_value": null,
  "array": [1, 2, 3],
  "object": {"nested": "value"}
}
数据类型 描述 示例
string 用双引号括起来的文本 "Hello"
number 整数或浮点数 42, 3.14
boolean 真或假值 true, false
null 表示值的缺失 null
array 有序的值列表 [1, 2, 3]
object 无序的键值对 {"key": "value"}

重要提示: JSON 不支持注释、尾随逗号、单引号、undefined、函数或原生日期对象。日期必须表示为字符串,通常采用 ISO 8601 格式。

何时使用 JSON

JSON 在特定场景中表现出色:

对于复杂的数据验证需求,请考虑使用我们的 JSON 格式化工具 来确保您的数据结构在部署前有效。

格式化标准

一致的格式化使 JSON 可读、可维护且更易于调试。遵循既定的约定可以减少错误并改善团队协作。

使用 2 空格缩进

两空格缩进是 JSON 的行业标准。它提供清晰的视觉层次结构,而不会产生过多的空白。

// ✅ 好:2 空格缩进
{
  "user": {
    "name": "Jane",
    "email": "[email protected]",
    "preferences": {
      "theme": "dark",
      "notifications": true
    }
  }
}

// ❌ 不好:无缩进(压缩)
{"user":{"name":"Jane","email":"[email protected]"}}

压缩的 JSON 适用于生产环境 API 以减少带宽,但始终为开发和文档维护格式化版本。

键名使用驼峰命名法

一致的键命名可防止混淆并使您的 JSON 更具可预测性。驼峰命名法是 JSON API 中最常见的约定。

// ✅ 好:驼峰命名法
{
  "firstName": "Jane",
  "lastName": "Smith",
  "emailAddress": "[email protected]",
  "createdAt": "2026-03-15T10:30:00Z",
  "isActive": true
}

// ❌ 避免混合样式
{
  "first_name": "Jane",      // 蛇形命名法
  "LastName": "Smith",       // 帕斯卡命名法
  "email-address": "...",    // 短横线命名法
  "CREATED_AT": "..."        // 大写蛇形命名法
}

专业提示: 如果您使用 Python 后端,可能会遇到蛇形命名法。选择一种约定并在整个 API 中坚持使用。如果需要,使用转换层在约定之间进行转换。

日期使用 ISO 8601 格式

由于 JSON 没有原生日期类型,始终使用 ISO 8601 格式字符串。这确保了在不同编程语言和时区之间的一致解析。

{
  "createdAt": "2026-03-15T10:30:00Z",           // UTC 时间
  "updatedAt": "2026-03-15T14:45:00+08:00",     // 带时区偏移
  "date": "2026-03-15",                          // 仅日期
  "time": "10:30:00"                             // 仅时间
}

使用有意义的键名

描述性的键使您的 JSON 具有自文档化特性,减少对外部文档的需求。

// ✅ 好:描述性键名
{
  "totalItemCount": 42,
  "isActive": true,
  "errorMessage": "Invalid email format",
  "maxRetryAttempts": 3
}

// ❌ 不好:晦涩的缩写
{
  "cnt": 42,
  "act": true,
  "err": "Invalid email format",
  "mra": 3
}

避免深层嵌套

深层嵌套的结构难以阅读和解析。目标是最多 3-4 层嵌套。

// ✅ 好:扁平结构
{
  "userId": "123",
  "userName": "Jane",
  "userEmail": "[email protected]",
  "addressStreet": "123 Main St",
  "addressCity": "Boston"
}

// ❌ 不好:过度嵌套
{
  "user": {
    "details": {
      "personal": {
        "name": {
          "first": "Jane"
        }
      }
    }
  }
}

验证技术

验证 JSON 可确保数据完整性并防止运行时错误。有多种验证方法,每种都适合不同的用例。

JSON Schema 验证

JSON Schema 是一种强大的词汇表,用于注释和验证 JSON 文档。它为您的 JSON 数据结构提供了契约。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    }
  },
  "required": ["name", "email"]
}

流行的 JSON Schema 验证器包括:

运行时验证

始终在运行时验证 JSON 数据,特别是在接收来自外部源或用户输入的数据时。

// JavaScript 示例,使用 try-catch
function validateJSON(jsonString) {
  try {
    const data = JSON.parse(jsonString);
    
    // 额外验证
    if (!data.email || !data.email.includes('@')) {
      throw new Error('Invalid email format');
    }
    
    return { valid: true, data };
  } catch (error) {
    return { valid: false, error: error.message };
  }
}

在线验证工具

在开发过程中进行快速验证,请使用在线工具,如我们的 JSON 格式化工具,它提供即时语法检查和格式化。您还可以使用 差异检查器 来比较 JSON 结构并识别差异。

快速提示: 设置预提交钩子,在提交到版本控制之前自动验证 JSON 文件。这可以在开发过程的早期捕获格式错误。

在 JavaScript 中解析 JSON

JavaScript 提供了处理 JSON 的原生方法。理解这些方法及其边缘情况对于构建健壮的应用程序至关重要。

JSON.parse() 方法

JSON.parse() 方法将 JSON 字符串转换为 JavaScript 对象。

const jsonString = '{"name":"Jane","age":30}';
const obj = JSON.parse(jsonString);

console.log(obj.name); // "Jane"
console.log(obj.age);  // 30

处理解析错误

始终将 JSON.parse() 包装在 try-catch 块中,以优雅地处理格式错误的 JSON。

function safeJSONParse(jsonString, fallback = null) {
  try {
    return JSON.parse(jsonString);
  } catch (error) {
    console.error('JSON parse error:', error.message);
    return fallback;
  }
}

// 使用方法
const data = safeJSONParse(userInput, { error: 'Invalid JSON' });

JSON.stringify() 方法

JSON.stringify() 方法将 JavaScript 对象转换为 JSON 字符串。

const obj = {
  name: "Jane",
  age: 30,
  hobbies: ["reading", "coding"]
};

// 基本用法
const jsonString = JSON.stringify(obj);

// 带缩进的美化打印
const formatted = JSON.stringify(obj, null, 2);

// 自定义替换函数
const filtered = JSON.stringify(obj, ['name', 'age']); // 仅包含特定键

使用 Reviver 函数进行高级解析

reviver 函数允许您在解析期间转换值,对于将日期字符串转换为 Date 对象很有用。

const jsonString = '{"name":"Jane","createdAt":"2026-03-15T10:30:00Z"}';

const obj = JSON.parse(jsonString, (key, value) => {
  if (key === 'createdAt') {
    return new Date(value);
  }
  return value;
});

console.log(obj.createdAt instanceof Date); // true

处理特殊值

了解 JavaScript 在 JSON 序列化期间如何处理特殊值:

const obj = {
  func: function() {},      // 函数被省略
  undef: undefined,         // undefined 被省略
  symbol: Symbol('test'),   // Symbol 被省略
  date: new Date(),         // 日期变为字符串
  nan: NaN,                 // NaN 变为 null
  infinity: Infinity        // Infinity 变为 null
};

console.log(JSON.stringify(obj));
// {"date":"2026-03-31T10:30:00.000Z","nan":null,"infinity":null}

专业提示: 在开发期间使用 JSON.stringify() 时将第三个参数设置为 2 以获得可读输出,但在生产环境中省略它以最小化负载大小。

在 Python 中解析 JSON

Python 的内置 json 模块为 JSON 操作提供了全面的支持。它快速、可靠,并且无需外部依赖即可处理大多数用例。

加载 JSON 数据

Python 提供了两种加载 JSON 的主要方法:json.loads() 用于字符串,json.load() 用于文件对象。

import json

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

# 从文件加载 JSON
with open('data.json', 'r') as file:
    data = json.load(file)

print(data['name'])  # "Jane"

导出 JSON 数据

同样,Python 提供了 json.dumps() 用于字符串,json.dump() 用于文件。

import json

data = {
    "name": "Jane",
    "age": 30,
    "hobbies": ["reading", "coding"]
}

# 转换为 JSON 字符串
json_string = json.dumps(data, indent=2)

# 写入文件
with open('output.json', 'w') as file:
    json.dump(data, file, indent=2)

处理自定义对象

Python 对象不能直接序列化为 JSON。对复杂类型使用自定义编码器。

import json
from datetime import datetime
from decimal import Decimal

class