{"orderId": "1234567890123456789"}
const id = JSON.parse(text, (k, v) =>
  k === 'orderId' ? String(v) : v);

后端返回 19 位订单号 1234567890123456789,前端 JSON.parse 后显示 1234567890123456800,用户把页面数据导出再导入,末四位全变成 0,对账差 400 单。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,JS 的 Number 只能精确表示到 2 的 53 次方,19 位整数已经超出范围,解析时低位被舍入。导入接口又按数字类型接收,错误值一路写进库。

「导入长整型精度」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。

处理上按这个顺序:后端把订单号序列化成字符串 不要输出数字;前端整个链路按字符串传递 不做 Number 转换;导入时校验长度和字符集 发现科学计数法或全 0 结尾直接拒绝。

改完只确认一件事:页面显示的订单号与原值逐位一致,导出再导入后末四位保持不变,对账条数对得上。

作者 9823189