当Number类型的id超过16位时,JavaScript的数据处理和储存问题

37 篇文章 0 订阅
24 篇文章 0 订阅

问题的背景:

当接口返回的Nubmer类型id长度超过16位,js在把返回的数据转为JSON格式时,会把长度超过16位的Number类型的数据做处理,处理的方式的裁取前十六位,十六位以后的数字都补为0.

(吐槽:不理解这种处理方式是咋样的脑回路???)

首先是怎么检查出这种问题:

如图,

1.在【响应】里面,可以看到正确的数据,就是超过十六位,且十六位以后的数字不为0的数据。

2.在【预览】里面,可以看到被转化为JSON的数据,此时超过16位的Number类型的数据已经被处理为错误数据

思考为什么会出现这种问题:

参考资料:

​​​​​​关于JavaScript中Number整数最大长度的一个疑问_mb5fe09d2d96fc4的技术博客_51CTO博客https://blog.51cto.com/u_15064069/3205654JS Number强类型转换数字超过16位精度丢失问题 - 简书问题图 Number转换19位(6145390195186705543)后结果为 6145390195186705000 造成原因:看网上资料说:js的number类型有个最...https://www.jianshu.com/p/d2eb9795c359百度安全验证https://baijiahao.baidu.com/s?id=1730543232132634655&wfr=spider&for=pc总结:

 js采用的是64位双精度

最小值为:Number.MIN_SAFE_INTEGER // -9007199254740991

最大值为:Number.MAX_SAFE_INTEGER // 9007199254740991

超出规定范围导致精度丢失 console.log(900719925474099177)

解决方式:

1.如果具体业务中后台返回的id超过16位,要让后台把id改为string类型 【个人觉得这是最优解】

2.BigInt 是一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。这原本是 Javascript中可以用Number表示的最大数字。BigInt 可以表示任意大的整数

3.拦截 【响应】的数据,用正则匹配修改 超过16位的Number类型数值 ,修改为String类型

 方式三的实践:

用的是axios做http请求,在Response里面加个拦截器,用正则匹配修改 超过16位的Number类型数值 ,修改为String类型

参考资料:

拦截器 | Axios 中文文档 | Axios 中文网https://www.axios-http.cn/docs/interceptorstransformResponse与axios的封装api_春风又一季的博客-CSDN博客_transformresponselet base = '';export const postRequest = (url, params) => { return axios({ method: 'post', url: `${base}${url}`,//Es6新语法 `${}` data: params, /* // `transformResponse` 在传递给 then/catch 前,允许修改响应数据 transformResponse: [functionhttps://blog.csdn.net/qq_40183281/article/details/107446718

export function QueryByPage(query) {
    return fetch({
        url: '/lapi/bankAccount/QueryByPage',
        method: 'post',
        data: query,
        behaviorRecord: {
            name: '银行账户查询-查询列表'
        },
        transformResponse: [function (data) {
            try {
                // 对 data 进行任意转换处理
                // /^\d{m,n}$/
                let reg = /\d{9,30}/g
                const tarArr = data.match(reg)
                const repArr = []
                
                // 最终输出的json
                let resutlt = JSON.parse(data)

                if (Array.isArray(tarArr)) {
                    for (let rep of tarArr) {
                        repArr.push({
                            key: [rep],
                            val: Number(rep)
                        })
                    }
                }

                if (Array.isArray(resutlt.data.records) && resutlt.data.records.length > 0) {
                    resutlt.data.records = resutlt.data.records.map(item => {
                        item.id = repArr.find(obj => obj.val === item.id).key
                        return item
                    })
                }

                return resutlt
            } catch (error) {
                console.error(error)
            }
        }]
    });
}

其他的方式,思路也大同小异,主要是对原始数据做拦截,然后把超长的Numer数据替换为String类型即可。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值