【精度丢失】后端接口返回的Long类型参数,不同浏览器解析出的结果不一样

文章讲述了同事在提供前端接口时遇到的问题,ID在火狐和谷歌浏览器中返回错误值。经分析发现是由于Long类型导致的精度丢失,解决方案是将Long类型改为String类型。

1、业务背景

有个同事找我帮他看一个问题,他给前端提供了一个接口。

这个接口是用来反查id的,他这里这个参数正常的返回值应该是 283232039247028226

但前端反馈他,前端在浏览器(火狐)获取的值是 283232039247028220(而且前端返回的这个值,并不存在于他的数据库中)。

而且他用浏览器(谷歌)进行访问返回的值也和前端一样是个错误值

Postman请求的值:

在这里插入图片描述

前端浏览器(火狐)请求的值:

在这里插入图片描述

2、问题分析

我用Edge浏览器进入前端页面查看,发现我这里返回的值和Postman是一致的

在这里插入图片描述

随后我去数据库查询他们得到的错误值,发现数据库是不存在的。既然数据库不存在,且不是所有浏览器都能复现,那应该就不是代码逻辑问题捞取到错误的值了。

随后我将正确的值、和他返回错误的值的值进行对比,发现整体是大致一样的,只有最后一位数不同。这个时候我就大概率感觉应该是精度损失的问题了!

随后一看他的代码,返回类型是用的Long类型的字段。百度得知前端JavaScript最大只能接收16位数字,故会导致精度丢失,以至于最后一位的6变成了0。(至于Edge为什么没有精度损失,怀疑可能是底层对其有一定的兼容)

3、解决方案

既然问题产生的原因已经很清晰了,那解决方案很简单,就是将原本的Long类型,修改为String类型,即可解决精度损失的问题。

4、总结

对于过长的id,尽量使用String进行存储和传递。因为你最多能确保在你这里是不会精度损失的,但你不能确保调用你接口的其他地方是以什么形式来解析你的id的。

### 前端处理后端返回Long 类型 ID 时避免精度丢失的方法 在处理后端返回Long 类型 ID 时,前端需要采取特定策略来避免精度丢失JavaScript 中的 `Number` 类型只能安全表示最多 53 位整数,而 Long 类型通常为 64 位,因此直接使用可能导致精度丢失[^4]。 #### 使用字符串类型传输 ID 最直接且推荐的方法是将 Long 类型转换为字符串进行传输。这样可以确保即使数值较大,也会因为超 JavaScript 的安全整数范围而丢失精度后端应修改 API 接口,将可能超安全整数范围的 Long 类型字段改为字符串类型返回[^2]。 ```json { "id": "1797913405167583236" } ``` 前端在接收到数据后,可以直接使用字符串形式的 ID,或者在需要进行数值运算时,使用 `BigInt` 类型进行处理。 #### 使用 `BigInt` 类型进行处理 JavaScript 提供了 `BigInt` 类型来处理任意精度的整数。如果前端需要对 ID 进行数值运算,可以将字符串转换为 `BigInt` 类型进行处理。 ```javascript const idStr = "1797913405167583236"; const idBigInt = BigInt(idStr); console.log(idBigInt); // 1797913405167583236n ``` 需要注意的是,`BigInt` 类型能与 `Number` 类型直接进行运算,必须进行显式转换,并且在某些环境中可能支持 `BigInt` 类型。 #### 保持数据一致性 为了确保在整个系统链路中的一致性和准确性,前端应确保接收到的数据是以字符串形式处理,并在需要的时候将其转换为适当的格式。这样可以避免由于数据类型转换当而导致的精度丢失问题[^2]。 ### 示例代码 以下是一个完整的示例代码,展示了如何从前端处理后端返回Long 类型 ID: ```javascript // 假设从后端获取的数据如下 const response = { id: "1797913405167583236" }; // 将字符串转换为 BigInt 类型 const idBigInt = BigInt(response.id); // 输结果 console.log(`String ID: ${response.id}`); // String ID: 1797913405167583236 console.log(`BigInt ID: ${idBigInt}`); // BigInt ID: 1797913405167583236n ``` ### 总结 通过将 Long 类型转换为字符串进行传输,并在前端使用 `BigInt` 类型进行处理,可以有效避免精度丢失问题。这种方法仅简单易行,而且能够确保在整个系统链路中的一致性和准确性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值