在JavaScript中,Number类型范围 -2^53 + 1 到 2^53 - 1,而
在Java中Long类型的取值范围是 -2^63 + 1 到 2^63 - 1
, 比JavaScript中大很多,所以后端能正常处理。
其实 ES6 引入了 Number.MAX_SAFE_INTEGER
和 Number.MIN_SAFE_INTEGER
这两个常量,用来表示这个范围的上下限。
Number.isSafeInteger()
用来判断一个整数是否落在这个范围之内,如果超出JS的Number范围的,看到的输出可能会有精度丢失问题的。
解决方案:
- 后端解决:后端直接给前端返回字符串,不要返回Number类型的数字
- 前端解决:
方案一: 正则
如果我们使用的是
axios
请求数据,Axios 提供了自定义处理原始后端返回数据的 API:transformResponse
, 可以这样处理:
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"
方案二:借助json-bigint
这个第三方包,进行json序列化
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"
强烈推荐公众号:程序员成长指北,我担心文章会删除或者不好找,所以在自己博客copy了一份,见谅哈,因为我之前也遇到过这个问题,当时是后端将返回参数改成了字符串,发现原来前端也有解决方案。不过,如果后端入参限制了必须传Number类型的id的话,也还是不行,所以还是后端改起来更方便。