前端大整数精度丢失:一次踩坑后的实战解决方案(`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

我在 axios 的 transformResponse 里用了 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" }

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

相关推荐
前端snow1 天前
ai agent --- postgreSQL 关系型数据库
前端
卷无止境1 天前
ECharts:把数据变成故事的可视化利器
前端
Eric_见嘉1 天前
在职前端 Skill 和 MCP 分享
前端·后端·agent
星河耀银海1 天前
数据解析:AI返回JSON数据在HTML5中的渲染方法
人工智能·json·html5
liangshanbo12151 天前
面试题:如何优化 Webpack 的打包速度?
前端·webpack·node.js
wengad1 天前
从 wangEditor 迁到 wangEditor-next
前端·javascript·vue.js
行者-全栈开发1 天前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
计算机魔术师1 天前
AMD砸82亿买下李飞飞,这次不卖芯片卖什么?
前端
hzxpaipai1 天前
杭州企业官网怎么建设?从策划到上线的5步建站方法
运维·服务器·前端·网络
怕浪猫1 天前
2026年金九银十,我面了22个前端
前端·javascript·面试