发现问题
在一个管理端项目中,调用编辑接口对列表内容进行更新。
列表内容一直未被更新,与后端对比如入参发现了问题:
- 我通过接口接收到的列表数据其中一条的 id 为 1564882714015404000。因此,此条数据进行编辑时,入参传入的主键 id 为 1564882714015404000。
- 实际上,我看到的数据是在 Preview(预览) 中展示的内容,也就是经过了 JS 反序列化的内容。而在 Response(响应) 中,发现此条数据的 id 为 1564882714015404033。
原因
- Number 类型的数据是 64 位双精度,能够安全表示的数据范围为 -253 ~ 253 , 即最大安全值为 9007199254740992,在我的项目中,后端传递的数据明显超出这个范围,造成了精度丢失,只保证了前 16 位的精度,16 位之后的数据,只用 0 表示。
解决方法
- 第一种:后端将此字段类型修改为 String 类型
- 第二种:前端在接收到响应数据时,反序列化之前,将此字段类型修改为 String 类型
- 此次我用到的就是这种解决方式,新封装一个 axios 实例,专门用来解决这种精度丢失的问题,在创建实例时,使用正则对 id 属性进行类型的转换
const transformResponse = function (res) {
res = res.replace(/\"id\":(\d+)/g, '"id":"$1"')
return JSON.parse(res)
}
const serviceTransform = axios.create({
transformResponse
});
- 第三种:JavaScript 新数据类型 BigInt
- 因此方法兼容性不符合当前项目,故放弃使用,后续再研究