后端返回long类型长度超出浏览器限制导致JS精度缺失,浏览器自动把超出部分用0表示解决方案

1.后端把返回值的字段减少一点
2.后端把返回值转成String类型,然后接收的时候把String类型转回long类型

但是1有场景限定
对于1来说 项目已经上线的话字段更改代价比较大,所以需要用到2方法
但是2方法对于前端来说有时候也并不是那么的好用
尽管后端返回的是字符串因为请求返回的时候会用JSON.parse(response)来解析后端返回的字符串这个时候就凉凉了,那么有办法解决吗?有的,不多CC直接上方法。

对接收的值作处理
const res = getRealJsonData(response.request.responseText); //直接放要解析的json字符串
function getRealJsonData(baseStr) {
    if (!baseStr || typeof baseStr != 'string') return;
    var jsonData = null;
    try {
        jsonData = JSON.parse(baseStr);
    } catch (err) {
        return null;
    }
    var needReplaceStrs = [];
    loopFindArrOrObj(jsonData, needReplaceStrs);
    needReplaceStrs.forEach(function (replaceInfo) {
        var matchArr = baseStr.match(eval('/"' + replaceInfo.key + '":[0-9]{15,}/'));
        if (matchArr) {
            var str = matchArr[0];
            var replaceStr = str.replace('"' + replaceInfo.key + '":', '"' + replaceInfo.key + '":"');
            replaceStr += '"';
            baseStr = baseStr.replace(str, replaceStr);
        }
    });
    var returnJson = null;
    try {
        returnJson = JSON.parse(baseStr);
    } catch (err) {
        return null;
    }
    return returnJson;
}
遍历数组类型
function getNeedRpStrByArr(arr, needReplaceStrs) {
    for (var i = 0; i < arr.length; i++) {
        var value = arr[i];
        loopFindArrOrObj(value, needReplaceStrs);
    }
}
递归遍历
function loopFindArrOrObj(value, needRpStrArr) {
    var valueTypeof = Object.prototype.toString.call(value);
    if (valueTypeof == '[object Object]') {
        needRpStrArr.concat(getNeedRpStrByObj(value, needRpStrArr));
    }
    if (valueTypeof == '[object Array]') {
        needRpStrArr.concat(getNeedRpStrByArr(value, needRpStrArr));
    }
}
遍历对象类型
function getNeedRpStrByObj(obj, needReplaceStrs) {
    for (var key in obj) {
        var value = obj[key];
        if (typeof value == 'number' && value > 9007199254740992) {
            needReplaceStrs.push({
                key: key
            });
        }
        loopFindArrOrObj(value, needReplaceStrs);
    }
}
浏览器精度测试
let num = 1616161616161616, num1 = 17171717171717171, num2 = 181818181818181818;
// 打印结果
num: 1616161616161616 // 没有变化,还顶得住
num1: 17171717171717172 // 结果好像只是+1了
num2: 181818181818181820 // 结果好像+2了

// 经过一系列的测试在17位的时候原数值有时候会+1,有时候不变,不知道什么情况。。。18位最后一位永远是0,倒数第二位好像没有规律可言,测试半天没发现什么规律

总结

使用这个方法可以在转义之前把精度会缺失的字符串在外面再包一层字符串 像这样子 '"111111111111111111"',这样子在解析的时候就能避免浏览器在使用JSON.parse()方法的时候把后端返回的字符串转成Number而导致超出浏览器限制范围(chrome是17位就开始作妖,18就补0)其他浏览器暂时没测试过,欢迎各位大佬科普

你可能感兴趣的:(后端返回long类型长度超出浏览器限制导致JS精度缺失,浏览器自动把超出部分用0表示解决方案)