程序笔记   发布时间:2022-07-19  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了request 请求大数精度丢失问题大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

背景

  • BFF Client 使用的 npm 包 request-promise-native 请求微服务接口返回 ID 精度丢失 > 1713166949059674112 => 1713166949059674000@H_450_6@

为什么会丢失?

  • 存储二进制时小数点的偏移量最大为52位,计算机存储的为二进制,而能存储的二进制为62位,超出就会有舍入操作,因此 JS 中能精准表示的最大整数是 Math.pow(2, 53),十进制即9007199254740992大于 9007199254740992 的可能会丢失精度
    • https://zhuanlan.zhihu.com/p/100353781@H_450_6@
    @H_450_6@
  • request-promise-native 发起请求时,当options.json 不为 false 会使用 JSON.parse 解析 body@H_450_6@
if (self._json) {
  try {
    response.body = JSON.parse(response.body, self._jsonReviver)
  } catch (E) {
    debug('invalid JSON received', self.uri.href)
  }
}

最小 demo

搭建服务 API

  • 搭建 Java Web Api:
    • :Building a RESTful Web service@H_450_6@
    • 修改 service 层使 id 最小值大于 js 精度限制@H_450_6@
    @H_450_6@
    public long getId() {
        return id + 1713166949059674112L;
    }
* 修改 controller 层添加 post 请求
    @PostMapping("/greeTing_create")
    public GreeTing createGreeTing(@requestParam(value = "name", DefaultValue = "World") String Name) {
        return new GreeTing(counter.incrementAndGet(), String.format(template, Name));
    }
  • 请求
    • GET 请求: curl http://localhost:8080/greeTing@H_450_6@
    • POST 请求:curl -X POST http://localhost:8080/greeTing_create@H_450_6@
    @H_450_6@
{"id":1713166949059674120,"content":"Hello, World!"}

解决方案

1. 获取响应体的字符串,使用 JSONbigid 转化成字符串

  • 优点:只影响当前请求@H_450_6@
  • 缺点:不支持 POST 请求方式,

    • 通过 json 传参数不支持@H_450_6@
    • 通过 form + json: false 传参数需要后端接口支持@H_450_6@
    @H_450_6@
  • GET 请求

    @H_450_6@
const rp = require('request-promise-native');
const jsonBigInt = require('json-bigint');

  const getOptions = {
    'method': 'GET',
    json: false,
    'url': 'http://localhost:8080/greeTing',
  };

  const getRes = await rp(getOptions);
  console.log('get result: ', jsonBigInt.parse(getRes));
  • POST 请求:不支持,json 被占用,一定会执行 JSON.parse@H_450_6@
const rp = require('request-promise-native');
const jsonBigInt = require('json-bigint');

  const postOptions = {
    'method': 'POST',
    'url': 'http://localhost:8080/greeTing_create',
    json: { name: 'CassTime' },
  };
  const postRes = await rp(postOptions);
  console.log('post result: ', jsonBigInt.parse(postRes));

2. 使用 JSONbig.parse() 替换 JSON.parse()

  • 优点:实现简单,支持 POST@H_450_6@
  • 缺点:影响所有的 JSON.parse() 解析@H_450_6@
const rp = require('request-promise-native');
const jsonBigInt = require('json-bigint');

async function jsonBigreplaceParse() {
  const oldParse = JSON.parse;
  JSON.parse = jsonBigInt.parse;
  const postOptions = {
    'method': 'POST',
    'url': 'http://localhost:8080/greeTing_create',
    json: { name: 'CassTime' },
  };
  const postRes = await rp(postOptions);
  console.log('post result: ', postRes);
  JSON.parse = oldParse;
}

大佬总结

以上是大佬教程为你收集整理的request 请求大数精度丢失问题全部内容,希望文章能够帮你解决request 请求大数精度丢失问题所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。