問題描述
后端把Long類型的數據傳給前端,前端可能會出現精度丟失的情況。例如:201511200001725439這樣一個Long類型的整數,傳給前端后會變成201511200001725440
相關概念
javaScript
的最大安全值:Number.MAX_SAFE_INTEGER 是一個值為 9007199254740991 的常量。因為 javaScript
的數字存儲使用了 IEEE 754 中規定的 雙精度浮點數 數據類型,而這一數據類型能夠安全存儲 -(2^53 - 1)
到 2^53 - 1 之間的數值(包含邊界值)。
// 也即 -(Math.pow(2, 53) - 1) 到 (Math.pow(2, 53) - 1),即 -9007199254740991 到 9007199254740991之間的數值(包含邊界值)
這里安全存儲的意思是指能夠准確區分兩個不相同的值,例如
Number.MAX_SAEF_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 將得到 true 的結果,而這在數學上是錯誤的
下圖可以看出,輸入的值超出安全值,可能會被js自動轉化

另外,javaScript
的最大值: Number.MAX_VALUE 其值為 1.7976931348623157e+308,代表js可表示的最大值,使用時可用來判斷某個值是否超出了 js 可表示的最大值
場景還原
使用 nodejs
起一個服務, 然后傳給前端一個Long類型的數值
const http = require('http')
const onRequest = function (request, response) {
console.log('---Request received---')
response.writeHead(200, {
'Content-Type': 'application/json'
})
var data = {
number: 201511200001725439 // (*)
}
response.end(JSON.stringify(data))
}
const server = http.createServer(onRequest)
server.listen(3000, '127.0.0.1')
console.log('Server started on localhost port 3000')
訪問 localhost:3000
{
"number": 201511200001725440
}
發現我們前端得到的數值和后端原本設置的數值不一樣
解決方案一
在后台將這個Long類型的字段轉換成String類型的,風險比較大
const http = require('http')
const onRequest = function (request, response) {
console.log('---Request received---')
response.writeHead(200, {
'Content-Type': 'application/json'
})
var data = {
number: '201511200001725439' // (*) // string
}
response.end(JSON.stringify(data))
}
const server = http.createServer(onRequest)
server.listen(3000, '127.0.0.1')
console.log('Server started on localhost port 3000')
再次訪問
{
"number": "201511200001725439"
}
這回發現前后端的數據完全一致,沒有出現精度丟失
解決方案二
使用 fastjson
的提供的注解,@JSONField(serializeUsing= ToStringSerializer.class)