js最大支持 9007199254740991 超过后就不正确了。所以接口在返回的时候转换为字符串给到前端即可避免前端精度丢失问题。
这里处理了多种情况,根据长度可自定调整【16,,20】正则
截止目前我们系统运行正常,暂未发生无法转换的问题
如果本身系统设计使用的id就是字符串就不需要处理
//将需要返回的对象转为字符串
if b, err := json.Marshal(responseData); err != nil {
panic(err)
} else {
reg := regexp.MustCompile(`(\d{16,20}),`)
l := len(reg.FindAllString(string(b), -1)) //正则匹配16-20位的数字,如果找到了就开始正则替换并解析
if l != 0 {
str := reg.ReplaceAllString(string(b), `"${1}",`) //执行替换
reg := regexp.MustCompile(`(\d{16,20})}`)
str = reg.ReplaceAllString(str, `"${1}"}`) //执行替换}
reg = regexp.MustCompile(`(\d{16,20})]`)
str = reg.ReplaceAllString(str, `"${1}"]`) //执行替换
var jdata interface{}
err := json.Unmarshal([]byte(str), &jdata)
if err != nil {
println("\njson解析失败", str)
panic(err)
}
responseData = jdata
}
}
目前上述使用了正则方式,除了{"price":3.9999999999999996}这种方式不正常,只是这种情况几乎不会出现,除非可能是极高精度要求的系统会使用这样的小数点。当然你也可以自定义正则完善这种情况
1.json树遍历
2.go内置的json包里的token处理后转为json
3.正则替换