在前后端联调时,发现后端有一个接口返回的值和前端页面上展示的值不一致。
后端Java实现接口,返回一个json格式的大整数 123456789123456788989,从控制台Network里看数据没错,但前端页面展示却有问题。
后来定位到: 在Js中,用Number来表示数字类型的值。Number类型总长度64位二进制bit,使用53位表示小数位,10 位表示指数位,1 位表示符号位。因此,Number整数的表示范围为 -2^53 ~ 2^53(不包含两端) 。在其他语言,如Java中,Long类型占64位二进制bit,最大值为:9223372036854774807(2^63 - 1)长度约19位。而在Js中,由于Number类型的值也包含了小数,最大值为:9007199254740993(2^53 - 1)长度约16位。
因此当Java返回超过16位的Long型字段转为json时,前端Js得到的数据将由于溢出而导致精度丢失。
解决方法: 虽然前端也可以解决问题,比如通过正则表达式解析替换、或者修改json parser,但比较麻烦,更推荐在后端解决。 非常简单,将可能超出范围的数字类型(Long)变量转为字符串类型(String)即可!