Nodejs中JSON.parse的这个BUG如何解决?
Nodejs中JSON.parse的这个BUG如何解决?
最近在公司用NODEJS做一个第三方应用,请求对方接口反馈的为JSON格式的数据,如下:
{"content": "Hi", "created_at": 1340863646, "type": "text", "message_id": 5758965507965321234, "from_user": "userC"}
其中message_id是19位number类型的。我用JSON.parse解析成JSON对象获取其中的信息,方法如下:
var jsonStr = '{"content": "Hi", "created_at": 1340863646, "type": "text", "message_id": 5758965507965321234, "from_user": "userC"}';
var jsonObj = JSON.parse(jsonStr);
console.log(jsonObj.message_id);//得到结果是:5758965507965321000
得到的结果的最后三位变成000了,请问如何处理?超过16位的数据解析后均会变为000;
目前用了个暂时规避的方法是,拿到json的string字符串,先把19位message_id的值两边加双引号,写的也有问题,有么有JS高手帮忙看看哈。
目前写的临时规避方案如下,是有BUG的:
//将message_id的19位数字两边加上双引号,避免JSON.PARSE时候,JS会对超过16位的数字转换错误
//JS/v8引擎都有这个BUG,如何处理?
return JSON.parse(jsonStr.toString().replace(/:\s\d{19}/g, ":\"@!#@!#$&\"").replace(/:\d{19}/g, ":\"@!#@!#$&\"").replace(/@!#@!#:\s/g,"").replace(/@!#@!#:/g,""));
在Node.js中使用JSON.parse
解析JSON字符串时,遇到超过16位的数字可能会出现精度丢失的问题。这是因为JavaScript中的数字类型(Number
)是基于IEEE 754标准的64位浮点数,其最大安全整数为Number.MAX_SAFE_INTEGER
,即2^53 - 1。
对于这个问题,我们可以采用以下几种解决方案:
解决方案一:将大数字作为字符串存储
最简单且有效的方法是确保这些大数字以字符串的形式存储,而不是数字形式。这样,当解析JSON字符串时,这些数字不会被当作数字处理,从而避免精度丢失。
var jsonStr = '{"content": "Hi", "created_at": 1340863646, "type": "text", "message_id": "5758965507965321234", "from_user": "userC"}';
var jsonObj = JSON.parse(jsonStr);
console.log(jsonObj.message_id); // 输出:5758965507965321234
解决方案二:使用第三方库
如果不能修改原始JSON数据,可以考虑使用一些第三方库来处理大数字。例如,json-bigint
库可以帮助正确解析大数字。
首先安装该库:
npm install json-bigint
然后使用该库进行解析:
const { JSONbig } = require('json-bigint');
var jsonStr = '{"content": "Hi", "created_at": 1340863646, "type": "text", "message_id": 5758965507965321234, "from_user": "userC"}';
var jsonObj = JSONbig.parse(jsonStr);
console.log(jsonObj.message_id); // 输出:5758965507965321234
总结
在Node.js中处理大数字时,最好的做法是将它们作为字符串存储。如果无法控制数据源,可以使用如json-bigint
这样的库来正确解析大数字。这不仅解决了精度丢失问题,还提高了代码的可读性和维护性。
js对超大数据不知道是怎么处理的,不像java一样,js好像对超过4个字节的数据就用科学计数法来存储的。楼主的message_id为什么不用字符类型呢。
这是是别人系统返回的,我们控制不了。
这个是正常的,涉及到js中number的最大值问题,请参看在Javascript中,最大的Number是多少?
请问对于这种直接获取到的json格式的字符串,你有没有什么好的建议哈?
有没有兄弟有写好的解决了这个错的JSON.parse()呢?
javascript 的数字类型是 64bit 浮点数,最大精度有限,您的值超出了这个范围,一共 19 位,
JS number 类型表示整数只能在 −9007199254740992 (−e53) and 9007199254740992 (e53) 这个范围内是精确的,这个只有 16 位,所以您的后3位自然就写 0 了。
e53 = 53/3 = 17.3*3 也就十进制 17 位所有的表达精度。
如果你非要使用数字类型,那么就没法解决。除非使用字符串型。
谢谢你的讲解,呵呵。可惜这个JSON字符串是对方接口返回的,我也没办法控制,所以就悲剧了。 {“content”: “Hi”, “created_at”: 1340863646, “type”: “text”, “message_id”: 5758965507965321234, “from_user”: “userC”}
JSON.parse方法的第二个参数是个回调,可以用来处理每个成员。
一个办法,在parse之前先把数字转化成字符串,要实现这个也很简单,先找到message_id的 位置,在找到:和,号的位置,在处理一下,貌似没有更好的办法了
正解
目前用的就是这个思路。。
目前用的就是这个思路。。