后端将高精度长整型转为字符串返回是最稳妥方案,因 JavaScript Number 精度上限为 ±9,007,199,254,740,991;前端应保持字符串使用,必要时用 BigInt 运算,禁用 Number()、+、parseInt 等强制转换。

JavaScript 中处理后端返回的高精度长整型(如 Java 的 Long、C# 的 long 或数据库中的 BIGINT)时,直接解析 JSON 会导致精度丢失,根本原因是 JavaScript 的 Number 类型基于 IEEE 754 双精度浮点数,安全整数范围仅为 -(2^53 - 1) 到 2^53 - 1(即 ±9,007,199,254,740,991)。超出该范围的整数(例如雪花 ID、订单号、用户 ID 等)在解析后末尾数字可能被“四舍五入”或归零。
后端主动转为字符串返回
最推荐、最稳妥的方案:后端在序列化 JSON 时,将高精度长整型字段统一转为字符串。这样前端拿到的就是原始字符串,完全规避精度问题。
- Java(Jackson)示例:用
@JsonSerialize(using = ToStringSerializer.class)注解标记字段,或全局配置ObjectMapper对Long类型启用字符串序列化 - Spring Boot 可通过
@Configuration添加SimpleModule,注册Long→String序列化器 - Node.js(Express + JSON.stringify)可借助
replacer函数对特定字段做String(value)处理 - 前端无需额外解析,直接使用
data.id(字符串),需要参与计算时再用BigInt(data.id)或保持字符串比较(如 ID 匹配、URL 参数等)
前端自定义 JSON 解析逻辑
若无法修改后端,可在前端接管 JSON 解析过程,识别并保留大数字为字符串。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 使用
JSON.parse(text, reviver)的reviver回调函数,对数值类型做范围判断:若typeof value === 'number'且!Number.isSafeInteger(value),则返回原字符串(需配合后端在 JSON 中保留原始字符串形式,或预处理文本) - 更可靠的做法是:后端在 JSON 中用特殊标记(如
"id": {"$numberLong": "12345678901234567890"}),前端reviver检测该结构并提取字符串 - 注意:
JSON.parse默认仍会把纯数字字面量转成Number,所以此法依赖后端配合格式改造,不能仅靠原始数字字面量挽救
使用 BigInt 进行运算(仅限需要计算场景)
当必须对大整数做算术运算(如递增 ID、比较大小)时,可用 BigInt,但要注意兼容性和限制。
立即学习“Java免费学习笔记(深入)”;
- 将字符串转为
BigInt("12345678901234567890123"),支持加减乘除、取模、位运算等 -
BigInt不能与Number混合运算(会报错),所有操作数都得是BigInt - 不支持
Math方法(如Math.floor)、不能用于JSON.stringify(会抛异常),需手动转回字符串存储或展示 - 兼容性:现代浏览器基本支持(Chrome 67+、Firefox 68+、Safari 14+),IE 完全不支持;服务端 Node.js ≥ v10.4.0
避免反模式:不要用 Number() 或 + 强转
常见错误写法:Number(jsonStr.id)、+jsonStr.id、parseInt(jsonStr.id) —— 这些都会立即触发精度丢失,即使原始字符串是精确的。
-
parseInt("90071992547409919")返回90071992547409920(已失真) -
Number("90071992547409919")同样返回90071992547409920 - 只要经过
Number类型,就落入 IEEE 754 表达极限,无法挽回 - 正确做法:全程保持字符串,仅在必要时用
BigInt构造















