遇到的问题:
后端返回的订单号是整型的,超过了Math.pow(2,53) = 9007199254740992,导致获取的数据失真。
类似问题:https://www.zhihu.com/question/34564427
解决方法及思路:
获取到后端的数据之后,将json字符串获取遍历,大于 9007199254740992的数值转为字符串,具体方法如下:
/** * 因为js中的Json.parse()会让Number数据类型精度丢失 */ 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('"' + replaceInfo.key + '":[0-9]{10,}'); 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 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); } } /** * 判断数据类型 */ 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)); } }
上面是转化的具体函数,接下来在返回数据的地方引用:
axios.post( url, data, { 'X-Request-Form': 'XHR', headers: { 'Authorization': 'Bearer ' + token }, responseType: 'text', transformResponse: [function ( data ) { return getRealJsonData( data ) }] } ).then( response => { console.log(response); });