今天写接口发现数据库里的 ID=33379319237636097 传到前端变成 33379319237636096
排查思路:
首先在统一返回那里加了 Debug 输出,发现正常。然后又加了个中间件:
package middleware
import (
"bytes"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type responseBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (r responseBodyWriter) Write(b []byte) (int, error) {
r.body.Write(b)
return r.ResponseWriter.Write(b)
}
func ResponseLogger(c *gin.Context) {
w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
c.Writer = w
c.Next()
if gin.IsDebugging() {
zap.L().Debug("[ResponseLogger] response: \n"+ w.body.String())
}
}
发现正常。
再看前端原始获取的数据:
{"code":200000,"message":"","result":{"items":[{"id":33379319237636097,"name":"","slug":"","weight":0}],"total":1,"page":0,"pageSize":0}}
正常。然而预览这里:
变成 33379319237636096 了
我又尝试把数据库的值改成 0
, 1
,结果又全部可以了。这说明只有是非常大的整数才会出问题。这个数是多少?改成 33379319237636097,33379319237636098,神奇的事情出现了,前端拿到的都是 33379319237636096。改成 33379319237636096 又可以了。改成 33379319237636100,也可以。改成 33379319237636099,奇怪了,又变成了 +1 问题:输出仍然是 100. 此时我怀疑大概率是缓存的缘故。
但我又试了几次,改成非常小的数字,却又马上生效了。
之后我在 axios 拦截器里输出:
{"code":200000,"message":"","result":{"items":[{"id":33379319237636096,"name":"","slug":"","weight":0}],"total":1,"page":0,"pageSize":0}}
还是 -1
我再用一个 API 调试工具测试:
结果正常。可以断定是前端的锅。
最终解决方法:
后端返回字符串形式的 ID