前端大整数精度丢失:一次踩坑后的实战解决方案(`json-bigint`)

最近在项目里处理企业信息接口,遇到一个很隐蔽的问题:

后端返回的企业 ID 明明是一个值,前端拿到后却"变了"。这是前端把大整数精度丢了

这篇就聊三件事:为什么会丢、什么时候丢、怎么彻底规避。


先看现象:两个数相等?

js 复制代码
9007199254740992 === 9007199254740993 // true

看到这个结果,很多人第一反应是"JS 出 bug 了"。

其实没有,这是 JavaScript 数值模型决定的。


原理:为什么会精度丢失?

JavaScript 的 number 底层是 IEEE 754 双精度浮点数

它并不是"任意精度整数",只有 53 位有效精度(含隐藏位)。

所以 JS 能安全表示的最大整数是:

js 复制代码
Number.MAX_SAFE_INTEGER // 9007199254740991(2^53 - 1)

一旦超过这个范围,就会出现:

  • 相邻整数无法都精确表示(中间会跳号)
  • 不同整数可能映射到同一个可表示值

这就是"大整数看起来被改了"的根因。


关键点:精度丢失通常发生在 JSON 解析阶段

很多同学以为是运算时才丢精度,其实在前端接收响应时就可能已经丢了。

比如后端返回:

json 复制代码
{ "id": 9876543210123456789 }

如果你直接走原生 JSON.parse,这个值会被转成 JS number

而超出安全范围后,精度损失通常是不可逆的。


我在项目里的方案:请求层统一接入 json-bigint

我在 axiostransformResponse 里用了 json-bigint,并配置:

  • storeAsString: true

意思是:大整数不要转 number,直接按字符串保存,确保"值不变形"。

实际代码(简化版)

ts 复制代码
import axios from 'axios'
import JSONbig from 'json-bigint'

const JSONbigParser = JSONbig({ storeAsString: true })

const service = axios.create({
  transformResponse: [
    function (data) {
      if (!data) return data
      try {
        // 用 JSONbig 解析,超大数字按字符串保留
        return JSONbigParser.parse(data)
      } catch (err) {
        console.warn('JSON 解析失败,返回原始数据', err)
        return data
      }
    },
  ],
})

用了以后会发生什么变化?

后端:

json 复制代码
{ "companyId": 9876543210123456789 }

前端拿到:

json 复制代码
{ "companyId": "9876543210123456789" }

精度保住了,值可回传、可比对、可展示。

相关推荐
文心快码BaiduComate1 分钟前
Comate搭载GLM-5.1:长程8H,对齐Opus 4.6
前端·后端·架构
熊猫钓鱼>_>7 分钟前
AI驱动的Web应用智能化:WebMCP、WebSkills与WebAgent的融合实践
前端·人工智能·ai·skill·webagent·webmcp·webskills
毛骗导演10 分钟前
OpenClaw Pi Agent 深度解析:嵌入式 Agent 运行时的架构设计与实现
前端·架构
twl11 分钟前
从 RAG 到可持续演化的知识库:llm-wiki 介绍
前端
傻小胖17 分钟前
Object.defineProperty() 完整指南
开发语言·前端·javascript
里欧跑得慢21 分钟前
Flutter 导航路由:构建流畅的应用导航体验
前端·css·flutter·web
@二进制22 分钟前
vue3+vant4+ts出现页面空白?甚至在App.vue的<template></template>中随便输入都无法显示?
前端·vue.js·typescript
桂森滨23 分钟前
Vue3+Pinia+Vite+TS 还原高性能外卖APP项目 4️⃣首页开发
前端·typescript·vue
我就是马云飞26 分钟前
大专毕业两年,我如何进入大厂,并逆袭八年的技术与认知成长
前端·程序员·全栈