前后端 JSON 交互的 10 个常见坑与解决方案

总结前后端 JSON 数据交互中的常见问题,包括数据类型不一致、日期格式、null 处理等,提供最佳实践。

JSON 工具 2026-05-29 9 分钟

前后端 JSON 交互的 10 个常见坑与解决方案

前后端通过 JSON 交互时,经常遇到各种问题。本文总结 10 个最常见的坑和解决方案。

坑 1:数字精度丢失

问题: JavaScript 的 Number 类型最大安全整数是 2^53 - 1,超过会丢失精度。

// ❌ 精度丢失
JSON.parse('{"id": 9007199254740993}')
// { id: 9007199254740992 }  ← 最后一位变了!

解决方案:

// 方案1:后端返回字符串
{ "id": "9007199254740993" }

// 方案2:使用 BigInt
BigInt("9007199254740993")

// 方案3:使用 json-bigint 库
const JSONbig = require('json-bigint');
JSONbig.parse('{"id": 9007199254740993}');

坑 2:日期格式不一致

问题: JSON 没有日期类型,不同系统格式不同。

// Java 返回的日期
{ "createTime": "2024-01-15T10:30:00.000+08:00" }

// 前端期望的格式
{ "createTime": "2024-01-15 10:30:00" }

// 有时甚至是时间戳
{ "createTime": 1705286400000 }

解决方案:

// 后端统一格式
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
// 前端统一处理
function formatDate(dateStr) {
  return new Date(dateStr).toLocaleString('zh-CN');
}

坑 3:null vs undefined

问题: Java 中 null 和 JavaScript 中 undefined 行为不同。

// JSON 中只有 null,没有 undefined
JSON.stringify(undefined)  // undefined(不是字符串)
JSON.stringify(null)       // "null"

// 访问不存在的属性
const obj = { name: "张三" };
obj.age       // undefined
obj.age ?? 0  // 0(空值合并)

解决方案:

// 使用空值合并运算符
const age = data.age ?? 0;

// 使用可选链
const city = data.address?.city ?? '未知';

坑 4:中文编码问题

问题: 中文字符在传输过程中可能乱码。

解决方案:

// 后端设置编码
produces = "application/json; charset=UTF-8"
// 前端确保正确解码
const response = await fetch(url);
const data = await response.json(); // 自动处理 UTF-8

坑 5:大数字作为 ID

问题: 数据库自增 ID 超过 JavaScript 安全整数范围。

解决方案:

// 后端返回字符串 ID
@JsonSerialize(using = ToStringSerializer.class)
private Long id;

坑 6:数组 vs 对象

问题: 空数组和空对象序列化结果不同。

JSON.stringify([])  // "[]"
JSON.stringify({})  // "{}"

// Java 中 List 和 Map 序列化结果也不同

坑 7:字段名大小写

问题: Java 驼峰命名 vs 数据库下划线命名。

// 使用注解统一
@JsonProperty("user_name")
private String userName;

坑 8:循环引用

问题: 对象之间相互引用导致序列化失败。

// ❌ 循环引用
class User {
    Order order;
}
class Order {
    User user;
}

// 解决:使用 @JsonIgnore
@JsonIgnore
private User user;

坑 9:枚举类型处理

问题: 前后端枚举值不一致。

// 后端返回枚举值
@JsonValue
private int code;
// 前端使用常量
const STATUS = {
  PENDING: 0,
  APPROVED: 1,
  REJECTED: 2
};

坑 10:空字符串 vs null

问题: 空字符串和 null 的处理逻辑不同。

// 区分空字符串和 null
if (data.name === '') {
  // 用户清空了输入
} else if (data.name === null) {
  // 字段未填写
} else {
  // 有值
}

最佳实践总结

  1. 统一日期格式:使用 ISO 8601 或时间戳
  2. ID 用字符串:避免大数字精度问题
  3. 字段名统一:使用驼峰或下划线,不要混用
  4. 空值处理:明确 null 和空字符串的区别
  5. 类型一致:前后端数据类型要对应
  6. 文档化:使用 Swagger/OpenAPI 文档化 API

总结

前后端 JSON 交互的问题大多源于数据类型和格式不一致。通过制定统一的规范、使用注解和工具,可以避免大部分问题。

📚 相关文章