1、问题场景:请求接口取得Number类型的数字和后端实际值不一致
比如:
后端返回10976458979374929,实际从接口拿到的是10976458979374928,在控制台也会得到这样的结果:
原因:
在JavaScript中,Number类型范围-2^53 + 1 到 2^53 - 1 。
ES6引入了Number.MAX_SAFE_INTEGER
和Number.MIN_SAFE_INTEGER
这两个常量,用来表示这个范围的上下限。
可以用Number.isSafeInteger()
用来判断一个整数是否落在这个范围之内
附:在Java中Long类型的取值范围是-2^63 + 1 到 2^63 - 1,比js处理数字范围大的多
解决方案:
- 后端解决:
方式1: 修改数据库存的类型为字符串
方式2:返回接口时转为字符串类型给前端 - 前端解决: response里转为字符串
方式1:正则替换
axios({
method: method,
url: url,
data: data,
transformResponse: [function (data) {
// 将Long类型数据转换为字符串
const convertedJsonString = data.replace(/"(\w+)":(\d{15,})/g, '"$1":"$2"');
return JSON.parse(convertedJsonString);
}],
})
// 假设后端返回的JSON数据如下:
const responseData = {
id: 12345678901234567890, // 这是一个Long类型数据
name: "John Doe"
};
// 处理过的json数据
console.log(responseData.id); // 这将输出字符串:"12345678901234567890"
console.log(typeof responseData.id); // 这将输出 "string"
方式2:json序列化处理
//借助json-bigint这个第三方包来处理
import JSONbig from "json-bigint";
axios({
method: method,
url: url,
data: data,
transformResponse: [function (data) {
const JSONbigToString = JSONbig({ storeAsString: true });
// 将Long类型数据转换为字符串
return JSONbigToString.parse(data);
}],
})
// 假设后端返回的JSON数据如下:
const responseData = {
id: 12345678901234567890, // 这是一个Long类型数据
name: "John Doe"
};
// 处理过的json数据
console.log(responseData.id); // 这将输出字符串:"12345678901234567890"
console.log(typeof responseData.id); // 这将输出 "string"
2、常用处理js精度缺失的第三方包
number-precision
主要方法:加减乘除(plus,minus,times, divides)以及求相近值(strip, round)
import NP from 'number-precision';
NP.plus(num1, num2, num3, ...) // num + num2 + num3
NP.minus(num1, num2, num3, ...) // num1 - num2 - num3
NP.times(num1, num2, num3, ...) // num1 * num2 * num3
NP.divide(num1, num2, num3, ...) // num1 / num2 / num3
NP.strip(num) // 取整
NP.round(num, ratio) // 四舍五入