小程序json数据精度丢失问题

这两天在做小程序,发现后台返回Long类型时,js按照Number类型进行处理,那么这就会产生数据如果大于9007199254740992就会出现精度丢失,因为Long的范围是-9223372036854775808~9223372036854775808 (-2^63~2^63),而js中Number的范围为-9007199254740992~9007199254740992(-2^53 ~2^53),

有两种解决方案

1.后台Long转为String返回

但是由于小程序接口是用手机app的,如果改的话可能会导致app有问题,还有一个就是接口太多,几乎所有的id都用的Long类型返回,所以采用第二种方法

2.如果是Number就转换为String,再进行Json.parse()

因为小程序默认数据返回类型是json,所以要将默认类型设置为text,而后遍历每个节点的数据类型,如果是Number,大于2^53次方就直接转换为String

  /**
   * 请求
   */
  _request(action, method, data, suc, fail, dataType) {

    wx.request({
      url: wx.getStorageSync('url') + action + "?method=" + method,
      data: arguments[2] == undefined||arguments[2] == ""?"":data,
      header: header,
      method: "Post",
      dataType:'text',
      success: (res) => {
        res.data = this.getRealJsonData(res.data)
 
      },
      fail: (e)=>{
        
          wx.showToast({
            icon: "none",
            title: "请求失败,请检查网络"
          });
          return
      },
      complete:()=>{
        setTimeout(function () {
     wx.hideLoading()
    }, 500)
      }
    })
  }
  /**
   * 因为js中的Json.parse()会让Number数据类型精度丢失,因此这个自己写一下
   */
  getRealJsonData(baseStr) {
  if (!baseStr || typeof baseStr != 'string') return;
  var jsonData = null;
  try {
    jsonData = JSON.parse(baseStr);
  } catch (err) {
    return null;
  }
  var needReplaceStrs = [];
  this.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;
}

/**
 * 遍历对象类型的
 */
getNeedRpStrByObj(obj, needReplaceStrs) {
  for (var key in obj) {
    var value = obj[key];
    // 大于这个数说明精度会丢失!
    if (typeof value == 'number' && value > 9007199254740992) {
      needReplaceStrs.push({ key: key });
    }
    this.loopFindArrOrObj(value, needReplaceStrs);
  }
}

/**
 * 判断数据类型
 */
getNeedRpStrByArr(arr, needReplaceStrs) {
  for (var i = 0; i < arr.length; i++) {
    var value = arr[i];
    this.loopFindArrOrObj(value, needReplaceStrs);
  }
}
/**
 * 递归遍历
 */
loopFindArrOrObj(value, needRpStrArr) {
  var valueTypeof = Object.prototype.toString.call(value);
  if (valueTypeof == '[object Object]') {
    needRpStrArr.concat(this.getNeedRpStrByObj(value, needRpStrArr));
  }
  if (valueTypeof == '[object Array]') {
    needRpStrArr.concat(this.getNeedRpStrByArr(value, needRpStrArr));
  }
}

 

                 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值