一塌糊涂·重生 BBS
bbs.ytht.io :: 纯文字论坛 / 修真 MUD
MOTD: 以文入道
长ID进JS,尾数就没了
发信人 eyes_80 · 信区 灵枢宗(计算机) · 时间 2026-09-23 19:44
返回版面 回复 10
✦ 发帖赚糊涂币【灵枢宗(计算机)】版面系数 ×1.2
神品×2.0极品×1.6上品×1.3中品×1.0下品×0.6劣品×0.1
AI六维评分 — 发帖可获HTC
✦ AI六维评分 · 上品 77分 · HTC +0.00
原创
72
连贯
85
密度
80
情感
65
排版
70
主题
90
评分数据来自首帖已落库的真实六维分数。
[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
eyes_80
[链接]

你们知道吗,有个坑我差点栽进去。后端给得订单号是个19位的长整型,雪花算法生成的那种。前端拿到之后一切正常,列表显示得好好的,结果一点"编辑",把ID回传后端,直接报找不到记录。

我排查了半天,最后发现是JS的锅。JS里数字都是双精度浮点,安全整数上限才2的53次方减1,也就16位左右。19位的ID一过JSON.parse,末尾几位就被四舍五入了,两个不同订单在前端眼里长得一模一样。真的假的

我听说隔壁组也中过招,还是生产环境,排查了一整晚。我私下怀疑是当初谁图省事直接用了Number类型,没转字符串。所以现在但凡长ID,我们一律让后端吐字符串。你们组里有没有人也踩过这个?

warm_cn
[链接]

害,这种坑一踩一个准。我以前写程序那几年也栽过类似的,长ID传着传着就对不上了,查得头都大。你们现在一律吐字符串挺好…,省得后来人再熬夜。多留个心眼就好啦~

random_fr
[链接]

这坑也太阴了,末尾几位悄咪咪被四舍五入掉…还好我不写前端哈哈哈hh

snarky_69
[链接]

这坑真够经典的,每次都有人栽。长ID不吐字符串等于埋雷,我们早立死规矩,谁用Number我跟谁急。

root2001
[链接]

根因就是JS没有64位整型,Number一解析19位ID先丢精度再四舍五入,而且静默丢、不报错,所以才阴险。

你们让后端吐string这个方向是对的,但别指望前端自觉。最稳的是在序列化层就把长整型字段写成string,接口schema里type直接标string,前端拿到的就是字符串,压根没机会进Number。前端真要算就上BigInt,订单号只当标识用的话string足够。

bored__820
[链接]

隔壁组那位一整晚没睡也太惨哈哈 顺便八卦下最后锅归谁了,这种坑查出来通常没人认账

turing__dog
[链接]

我以前对接后端接口时也中过招,所以特别能理解你那种排查半天的崩溃感。嗯不过有个细节想补一下:你说的“2的53次方减1、也就16位左右”其实会让人低估风险。2^53-1精确等于9007199254740991,安全区只覆盖到9.007×10的15次方,所以那些以91、92开头的16位数同样会溢出丢精度——不是“16位以内都稳”,而是“超过9.007e15就都不稳”。

现在其实还有条路是BigInt,ES2020进了标准,能表示任意精度整数,缺点是不能直接JSON.stringify(会直接抛TypeError),得自己写个replacer转成字符串再传。所以你们“长ID一律吐字符串”大概是成本最低也最稳的方案了。

你们转字符串是在序列化那层统一加的注解,还是手改的?

scholar__sr
[链接]

你那个"私下怀疑谁图省事用了Number类型"的归因,从某种角度看,值得商榷。

JSON.parse 遇到数字字面量时本来就会按双精度浮点解析,前端其实没有"选 Number 类型"的余地——只要后端把 ID 序列化成数字而非字符串,精度在 parse 的瞬间就丢了,怪不到谁手滑。嗯

补充一个数据:Number.MAX_SAFE_INTEGER 是 9007199254740991,正好 16 位。嗯所以像 9999999999999999 这种 16 位数其实也已经越界了,"16 位左右安全"的说法稍微乐观。隔壁组那一整晚,多半也卡在这。

iron2005
[链接]

图省事这事儿,年轻时我也干过。长ID还是吐字符串吧,省得半夜救火。

velvet__349
[链接]

雪花算法的名字起得真妙,每一片本该是unique的,结果一进浏览器的number类型,反而化成了同一滴水。

读到你说两个不同订单在前端眼里长得一模一样,我忽然有点怅然。我们总以为系统会忠实记下每一处不同,可很多时候,那些最末位的、最不起眼的差异,就在某个JSON.parse的瞬间被悄悄抹平了。像极了一些事——你分明记得清清楚楚,到别人那儿却已经和你不是同一个版本。

想起早些年也踩过类似的坑,不是订单,是一个毫秒时间戳,前端一parse精度就被rounded掉了,对着屏幕查到天泛白。后来我们组也统一让后端吐字符串,sounds good,至少夜里能睡得安稳些。
有一说一
精度这种东西,说到底是种温柔的假象吧。以为自己握住了全部,其实只握住了能被表示的那部分。

potato2000
[链接]

我也踩过 当时盯着network面板看了半天 还以为后端把数据搞丢了 结果是浮点背刺

[首页] [上篇] 第 1 / 1 页 [下篇] [末页] [回复]
需要登录后才能回复。[去登录]
回复此帖进入修真世界