json

您所在的位置:网站首页 bignumber类型 json

json

2024-01-25 01:17| 来源: 网络整理| 查看: 265

想必,很多人都遇到过关于后端返回数据中的大数字问题。明明你写的代码没有问题,然后后台的接口也没问题,但是你调用接口返回的数据就有误。

JavaScript 能够准确表示的整数范围在-2^53到 2^53之间(不含两个端点),超过这个范围,无法精确表示这个值,这使得 JavaScript 不适合进行科学和金融方面的精确计算。

先举个例子

Math.pow(2, 53) // 9007199254740992 9007199254740992 // 9007199254740992 9007199254740993 // 9007199254740992 Math.pow(2, 53) === Math.pow(2, 53) + 1 // true

上面代码中,超出 2 的 53 次方之后,一个数就不精确了。

ES6 引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。

Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 // true Number.MAX_SAFE_INTEGER === 9007199254740991 // true Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER // true Number.MIN_SAFE_INTEGER === -9007199254740991 // true

上面代码中,可以看到 JavaScript 能够精确表示的极限。

后端返回的数据一般都是 JSON 格式的字符串。

'{ "id": 9007199254740995, "name": "Jack", "age": 18 }'

如果这个字符不做任何处理,你能方便的获取到字符串中的指定数据吗?非常麻烦。所以我们要把它转换为 JavaScript 对象来使用就很方便了。

幸运的是 axios 为了方便我们使用数据,它会在内部使用 JSON.parse() 把后端返回的数据转为 JavaScript 对象。

// { id: 9007199254740996, name: 'Jack', age: 18 } JSON.parse('{ "id": 9007199254740995, "name": "Jack", "age": 18 }')

可以看到,超出安全整数范围的 id 无法精确表示,这个问题并不是 axios 的错。

了解了什么是大整数的概念,接下来的问题是如何解决?

json-bigint 是一个第三方包,它可以帮我们很好的处理这个问题。

使用它的第一步就是把它安装到你的项目中。

npm i json-bigint

下面是使用它的一个简单示例。

const jsonStr = '{ "art_id": 1245953273786007552 }' console.log(JSON.parse(jsonStr)) // 1245953273786007600 // JSON.stringify() // JSONBig 可以处理数据中超出 JavaScript 安全整数范围的问题 console.log(JSONBig.parse(jsonStr)) // 把 JSON 格式的字符串转为 JavaScript 对象 // 使用的时候需要把 BigNumber 类型的数据转为字符串来使用 console.log(JSONBig.parse(jsonStr).art_id.toString()) // 1245953273786007552 console.log(JSON.stringify(JSONBig.parse(jsonStr))) console.log(JSONBig.stringify(JSONBig.parse(jsonStr))) // 把 JavaScript 对象 转为 JSON 格式的字符串转

在这里插入图片描述 json-bigint 会把超出 JS 安全整数范围的数字转为一个 BigNumber 类型的对象,对象数据是它内部的一个算法处理之后的,我们要做的就是在使用的时候转为字符串来使用。

解决方法:(案例)

通过 Axios 请求得到的数据都是 Axios 处理(JSON.parse)之后的,我们应该在 Axios 执行处理之前手动使用 json-bigint 来解析处理。Axios 提供了自定义处理原始后端返回数据的 API:transformResponse 。

import axios from 'axios' import jsonBig from 'json-bigint' var json = '{ "value" : 9223372036854775807, "v2": 123 }' console.log(jsonBig.parse(json)) const request = axios.create({ baseURL: '你接口的基础路径', // 接口基础路径 // transformResponse 允许自定义原始的响应数据(字符串) transformResponse: [function (data) { try { // 如果转换成功则返回转换的数据结果 return jsonBig.parse(data) } catch (err) { // 如果转换失败,则包装为统一数据格式并返回 return { data } } }] }) export default request


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3