js精度丟失解決方案(響應(yīng)和預(yù)覽數(shù)據(jù)不一致)
背景
后端使用雪花算法生成的id,在接口文檔測試中,響應(yīng)體中正常顯示。
在后續(xù)測試中,卻出現(xiàn)通過id查不到數(shù)據(jù)的情況,通過打開瀏覽器控制臺(F12)發(fā)現(xiàn),響應(yīng)和預(yù)覽中的數(shù)據(jù)不一致。
從下面圖片可以看出,響應(yīng)中JSON格式的數(shù)據(jù)是正常的,但是在預(yù)覽中卻出現(xiàn)跟原id不一致的情況,且通過分析發(fā)現(xiàn)只有最后兩位不一致,這里明顯出現(xiàn)了精度丟失

這里的id是正常的

在這里出現(xiàn)了精度丟失

問題分析
1. JavaScript 的數(shù)字精度限制
JavaScript 使用 IEEE 754 雙精度浮點數(shù)格式表示所有數(shù)字,這意味著:
- 它能準確表示的整數(shù)范圍是
-2^53 + 1到2^53 - 1(即-9007199254740991到9007199254740991) - 你的 ID
1922304585509261314已經(jīng)超過了這個范圍(2^53 = 9007199254740992)
2. 當數(shù)字超過安全整數(shù)范圍時
超出 Number.MAX_SAFE_INTEGER(即 2^53 - 1)的數(shù)字會出現(xiàn)精度丟失(前端測試):
const bigId = 1922304585509261314; console.log(bigId); // 輸出 1922304585509261300
為什么預(yù)覽顯示不正確?
開發(fā)工具(如瀏覽器控制臺、Postman等)在顯示 JSON 響應(yīng)時,會自動將數(shù)字類型的值轉(zhuǎn)換為 JavaScript 數(shù)字,從而導(dǎo)致精度丟失。實際響應(yīng)數(shù)據(jù)可能是正確的,但顯示時被轉(zhuǎn)換了。
解決方案
后端解決方案:
代碼
SpringBoot中可以通過編寫JsonConfig處理json精度丟失的配置,將Long類型轉(zhuǎn)化為String類型
@JsonComponent
public class JsonConfig {
/**
* 添加 Long 轉(zhuǎn) json 精度丟失的配置
*/
@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, ToStringSerializer.instance);
module.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(module);
return objectMapper;
}
}代碼解釋
1. @JsonComponent 注解
- 這個注解是 Spring Boot 提供的,用于標記一個類作為 Jackson 的序列化/反序列化組件。
- 被標記的類會自動注冊到 Spring 的 Jackson
ObjectMapper中,全局生效。
2. JsonConfig 類
public class JsonConfig {- 這是一個配置類,專門用于自定義 Jackson 的 JSON 序列化行為。
3. jacksonObjectMapper 方法
@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {@Bean表示這個方法會返回一個由 Spring 管理的 Bean(這里是ObjectMapper)。Jackson2ObjectMapperBuilder是 Spring Boot 提供的工具類,用于方便地配置ObjectMapper。
4. 創(chuàng)建和配置 ObjectMapper
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
- 通過
builder創(chuàng)建一個新的ObjectMapper實例,并禁用 XML 映射功能(createXmlMapper(false))。
5. 注冊自定義序列化模塊
SimpleModule module = new SimpleModule(); module.addSerializer(Long.class, ToStringSerializer.instance); module.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(module);
SimpleModule:是 Jackson 提供的模塊,用于自定義序列化/反序列化規(guī)則。module.addSerializer:
Long.class:針對包裝類型的Long。Long.TYPE:針對基本類型的long。ToStringSerializer.instance:將Long值直接轉(zhuǎn)換為字符串(而不是數(shù)字),避免精度丟失。
objectMapper.registerModule(module):將配置好的模塊注冊到ObjectMapper。
6. 返回配置好的 ObjectMapper
return objectMapper;
- 最終返回定制化的
ObjectMapper,Spring 會用它來處理所有 JSON 序列化/反序列化。
修改后測試

id已經(jīng)轉(zhuǎn)為字符串,顯示正常,無精度丟失
總結(jié)
- JavaScript 的
Number類型無法安全表示超過 53 位的整數(shù)(2^53),而 Java 的Long是 64 位。 - 如果直接將
Long作為數(shù)字序列化到 JSON,前端 JavaScript 解析時可能會丟失精度(例如1234567890123456789可能變成1234567890123456800)。 - 解決方案:將
Long序列化為字符串(如"1234567890123456789"),前端可以通過字符串解析避免精度問題。
到此這篇關(guān)于js精度丟失解決方案的文章就介紹到這了,更多相關(guān)js精度丟失解決內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS解決IOS中拍照圖片預(yù)覽旋轉(zhuǎn)90度BUG的問題
下面小編就為大家?guī)硪黄狫S解決IOS中拍照圖片預(yù)覽旋轉(zhuǎn)90度BUG的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
理運用命名空間讓js不產(chǎn)生沖突避免全局變量的泛濫
為了避免變量之間的覆蓋與沖突,可以生成命名空間,命名空間是一種特殊的前綴,在不同的匿名函數(shù)中,根據(jù)功能聲明一個不同的命名空間2014-06-06
利用HTML與JavaScript實現(xiàn)注冊頁面源碼
這篇文章主要給大家介紹了關(guān)于利用HTML與JavaScript實現(xiàn)注冊頁面的相關(guān)資料,文中通過代碼介紹的非常詳細,對大家實現(xiàn)注冊頁面具有一定的參考借鑒價值,需要的朋友可以參考下2023-12-12

