今天写接口发现数据库里的 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}}

正常。然而预览这里:

image-20210819155233474

变成 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 调试工具测试:

image-20210819161531555

结果正常。可以断定是前端的锅。

最终解决方法:

后端返回字符串形式的 ID