目录
- 问题描述
- 问题分析
- 解决办法
- 参考文章
问题描述
Java后端接口返回17位长度的数值,JavaScript前端接收错误
例如:
console.log(10976458979374929)
10976458979374928
可以看到,输出的数值不一致,精度丢失了
问题分析
查看JavaScript Number类型的数值范围,16位长度
console.log(Number.MIN_SAFE_INTEGER)
-9007199254740991
console.log(Number.MAX_SAFE_INTEGER)
9007199254740991
查看Java Long类型的数值范围,19位长度
System.out.println(Long.MIN_VALUE);
//-9223372036854775808
System.out.println(Long.MAX_VALUE);
// 9223372036854775807
比较
语言 | 数据类型 | 最小值 | 最大值 |
JavaScript | Number | -(2^53 - 1) = -9007199254740991 | (2^53 - 1) = 9007199254740991 |
Java | Long | (-2^63) = -9223372036854775808 | (2^63 - 1) = 9223372036854775807 |
文档
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number
- https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html
解决办法
- 方式1:数据库字段类型修改为字符串
- 方式2:后端返回数据将Long类型转为字符串
- 方式3:前端json反序列的之前对字符串处理
方式1和方式2需要和后端沟通,如果沟通无效,也可以前端自行处理
一个简单的方式是使用第三方库 json-bigint 来解析json
安装
npm i json-bigint
使用示例
import JSONbig from "json-bigint";
// 后端返回的数据
const data = '{"uid": 10976458979374929, "age": 20}';
// 使用内置JSON解析
console.log(JSON.parse(data));
// { uid: 10976458979374928, age: 20 }
// 使用第三方库JSONbig解析
const JSONbigToString = JSONbig({ storeAsString: true });
console.log(JSONbigToString.parse(data));
// { uid: '10976458979374929', age: 20 }
参考文章
- 线上紧急Bug:80%前端可能会遇到的数据精度问题