利用json

您所在的位置:网站首页 bigint数据类型js 利用json

利用json

2023-08-13 14:19| 来源: 网络整理| 查看: 265

关于后端返回数据中的大数字问题

假设后端需要根据传入的id来返回请求的数据,而传入的id超过了-2^53到2^53的范围,此时就无法接收准确的id,这样就会导致后端拿不到正确的id,导致出现404的错误

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处理大数字问题

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

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

npm i json-bigint 复制代码

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

const jsonStr = '{ "art_id": 1245953273786007552 }' ​ console.log(JSON.parse(jsonStr)) // 1245953273786007600 ​ // 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 格式的字符串转 复制代码

1582099315865-5e805425-7abf-4cf2-9df3-acc2ef8f9bb9.png

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

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

截屏2021-09-01 上午9.23.21.png

5731630397570_.pic_hd.jpg

在src/utils/request.js处理axios文件中进行配置

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: 'http://ttapi.research.itcast.cn/', // 接口基础路径 ​  // transformResponse 允许自定义原始的响应数据(字符串)  transformResponse: [function (data) {    try {      // 如果转换成功则返回转换的数据结果      return jsonBig.parse(data)   } catch (err) {      // 如果转换失败,则包装为统一数据格式并返回      return {        data     }   } }] }) ​ export default request ​ 复制代码

修改props类型

props: {    articleId: {      type: [Number, String, Object],      required: true   } } 复制代码

扩展:ES2020 BigInt

ES2020 引入了一种新的数据类型 BigInt(大整数),来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

参考链接:

developer.mozilla.org/zh-CN/docs/… es6.ruanyifeng.com/#docs/numbe…


【本文地址】


今日新闻


推荐新闻


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