原因:js特性不支持 2的53次方 以上的数值,造成数字不准确
example: 12345678901234567123 会被解析成12345678901234567000
不管是前端解决还是后端解决,归根结底都是将long型数字转换成字符串
遇到这种问题,最好可以让后端同学在接口返回数据时直接将long型转成string。
前端解决方案
在response中拿到的数据是正确的,这时是一个字符串,但是在preview中精度就丢失了。所以前端如果想处理,只能在这一层处理。因为时间比较紧急,我目前是使用的第一种方法,第二种方法大家可以自行去参考。
- 项目中使用的是axios, 用正则断言将long型数字替换成字符串。
不了解断言的同学可以搜一下相关知识,这里就不细说了
// example:返回的数据中id是long型
// response 是这样的 '{"success":true,"msg":"成功","data":{"id":1234567890123456789}}'
// 断言 "id": 后面是数字,将 "id": 后端数字替换为字符串 替换后为 '{"success":true,"msg":"成功","data":{"id":“1234567890123456789”}}'
const opt = {
method: 'post',
url: '/api/data',
transformResponse: [response => JSON.parse(response.replace(/(?<="id":)(\d{0,})/g, '"$1"')]
}
axios(opt).then(() => {
// do something
})
你也有可能这么想: response.replace(/(\d{16,})/g, '"$1"')
直接将超过16位的数字装换成字符串,⚠️注意了,这么写是有问题的,如: '{"id":"1234567890123456789"}'
会被替换成'{"id":""1234567890123456789""}'
- 从JSON.parse入手,不使用原始的JSON.parse方法。重新定义json的转换方法。
Jison
参考文章一: https://juejin.im/post/5c51526fe51d455047338a2a
参考文章二: https://blog.csdn.net/fifteen718/article/details/82783246
后续
火狐浏览器不支持断言/预搜索,出现兼容性问题。
那就只能换一种方式了。我在这里使用了分组匹配。在数字前后加【"】引号
// $0 标识全部的匹配, $1表示 【"id":】$2就是数字 $3表示【,】
str.replace(/("id":)(\d{0,})(,)/g, '$1'+'"'+'$2'+'"'+'$3')