后端Long型数据传到前端js后精度丢失的问题(前后端传输踩坑指南)

在全栈开发中,遇到过这样一个"诡异"的问题:

后端返回一个 Long 类型 ID,前端接收到后却变了值 😨

比如:

json 复制代码
{
  "id": 9007199254740993
}

前端 JS 打印出来却是:

javascript 复制代码
9007199254740992

这不是 bug,这是经典的精度丢失问题

出现这种问题,可以做一个测试:在浏览器的Network(网络)面板中,不要看Preview(预览)标签页,而是点开Response(响应/原始数据)标签页。你会发现,原始的纯文本字符串是正常的,但只要经过工具的"美化/格式化"它就会因为超出JS安全整数范围,被自动进位,进而改变数据呈现方式。

你用来查看接口返回数据的工具(比如浏览器的Network面板、Postman、Swagger 等),它们底层在格式化展示 JSON 时,也是用 JavaScript 解折的!


文章目录

    • 一、问题本质
      • [1. Java 的 Long 是什么?](#1. Java 的 Long 是什么?)
      • [2. JavaScript 的 Number 是什么?](#2. JavaScript 的 Number 是什么?)
      • [⚠️ 超过这个值会发生什么?](#⚠️ 超过这个值会发生什么?)
    • 二、典型场景
    • 三、解决方案
    • [方案一:后端转 String(最推荐 ⭐)](#方案一:后端转 String(最推荐 ⭐))
    • [方案二:前端使用 BigInt](#方案二:前端使用 BigInt)
    • [方案三:前端使用 JSON 解析库](#方案三:前端使用 JSON 解析库)
    • 不推荐方案
      • [方案:强行用 Number](#方案:强行用 Number)
    • [🧩 四、最佳实践总结](#🧩 四、最佳实践总结)
    • 参考

一、问题本质

1. Java 的 Long 是什么?

在 Java 中:

java 复制代码
Long.MAX_VALUE = 9223372036854775807

👉 64 位整数(long),精度完全没问题。


2. JavaScript 的 Number 是什么?

在 JavaScript 中:

  • 所有数字都是 Number
  • 基于 IEEE 754 双精度浮点数

👉 最大安全整数:

javascript 复制代码
Number.MAX_SAFE_INTEGER === 9007199254740991

⚠️ 超过这个值会发生什么?

javascript 复制代码
9007199254740991 + 1 === 9007199254740992 // ✅
9007199254740991 + 2 === 9007199254740992 // ❌ 精度丢失

👉 这就是为什么 Long 在 JS 中会"变"。


二、典型场景

后端返回

java 复制代码
@Data
public class User {
    private Long id;
}

接口返回:

json 复制代码
{
  "id": 9223372036854775807
}

前端接收

javascript 复制代码
console.log(res.id);
// 输出:9223372036854776000 ❌

👉 精度直接炸掉。


三、解决方案


方案一:后端转 String(最推荐 ⭐)

✔ 原理

👉 避免 JS 解析为 Number,直接作为字符串处理。


✔ 实现方式(Jackson)

使用 @JsonSerialize

java 复制代码
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

public class User {

    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
}

全局配置(推荐)

java 复制代码
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.serializerByType(Long.class, ToStringSerializer.class)
                             .serializerByType(Long.TYPE, ToStringSerializer.class);
}

返回结果

json 复制代码
{
  "id": "9223372036854775807"
}

前端处理

javascript 复制代码
const id = res.id; // string

👉 安全 ✅ 无损 ✅


方案二:前端使用 BigInt

适用场景

  • 需要参与计算
  • 不只是展示

示例

javascript 复制代码
const id = BigInt("9223372036854775807");
console.log(id + 1n);

⚠️ 注意

  • 必须加 n
  • 不能和普通 Number 混用
javascript 复制代码
1n + 1 // ❌ 报错

方案三:前端使用 JSON 解析库

比如:

  • json-bigint

地址:https://www.npmjs.com/package/json-bigint


示例

javascript 复制代码
import JSONbig from 'json-bigint';

const data = JSONbig.parse(responseText);

console.log(data.id.toString());

优点

  • 自动处理大整数
  • 不需要改后端

缺点

  • 增加依赖
  • 性能略低

不推荐方案

方案:强行用 Number

javascript 复制代码
parseInt(res.id)

👉 依然会丢精度,没意义。


🧩 四、最佳实践总结

方案 推荐指数 说明
后端转 String ⭐⭐⭐⭐⭐ 最稳定,最通用
BigInt ⭐⭐⭐⭐ 适合计算
json-bigint ⭐⭐⭐ 特殊场景
直接 Number 一定会出问题

参考

使用axios请求,前端数字long类型精度问题解决方法-CSDN博客

长得太长也是错?------后端 Long 型 ID 精度丢失的"奇妙"修复之旅-腾讯云开发者社区-腾讯云

解决后端Long型数据传到前端js后精度丢失的问题-知乎

相关推荐
oi..2 小时前
CSRF安全攻防:Referer 校验与 Token 防护详解
前端·网络·笔记·测试工具·安全·网络安全·csrf
申耀的科技观察2 小时前
【观察】昂瑞微5G射频前端通过车规认证,筑牢智能网联汽车通信安全“底座”
前端·5g·汽车
qq_260241232 小时前
将盾CDN:Web应用防火墙(WAF)的工作原理与实战配置
前端·网络·安全
旺王雪饼 www2 小时前
《Express框架深度解析:从基础入门到高级实践与项目架构》
前端·node.js·express
时寒的笔记2 小时前
js7逆向案例_禁止f12打开&sojson打开
开发语言·javascript·ecmascript
stpzhf2 小时前
uniapp nvue组件多个text在一行并且高亮其中一些文字
前端·javascript·uni-app
Seven972 小时前
【从0到1构建一个ClaudeAgent】规划与协调-子Agent
java
宠友信息2 小时前
社交软件源码哪个渠道好
java·微服务·架构·社交电子·springboot·uniapp
十一.3662 小时前
003-004 虚拟DOM的两种创建方式、虚拟DOM与真实DOM
前端·javascript·html