【Vite】Vite设置好了Proxy接口却404...解决方案来了

8 篇文章 0 订阅

前言

最近在做一个ERP的项目,里面涉及到了很多的计算,尤其特别是有很多关于浮点数的计算,然后就碰到了下面的问题。

问题描述 & 解决方案

1.使用toFixed or Math.round进行四舍五入&保留两位小数会有5不进1的情况

举个🌰,我在开发的过程中遇到了321201.595这个数字…

然后我想对他进行四舍五入 & 保留两位小数,一开始不太了解 toFixed有那么多坑,所以直接用的.toFixed(2),结果如下:

const number = 321201.595;
console.log(number.toFixed(321201.595)) // '321201.59'

没错,结果不对,少了那么0.01,后端算出来是321201.60,所以校验不通过,我得再处理,网上翻了很多资料,都说用Math.round可以做到四舍五入 & 保留两位小数,是这么做的,结果如下:

const number = 321201.595;
console.log(Math.round(number * 100) / 100) // 321201.59

没错,结果还是不对!!!WTF!!

这里说一下toFixed & Math.round

toFixed 😭

toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。例如将数据Num保留2位小数,则表示为:toFixed(Num);但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法

网上是这么说的:五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一

但是我跑了一遍发现,好像不对啊,5前为奇数的时候,只有321201.575; 321201.5151了,相反5前面为偶数的时候除了321201.545 其他的都会进1。

可以证实的是,如果5后面还有数值,那就会直接进1,参考321201.5951

继续用上面的321201.595举个🌰:

console.log(321201.595.toFixed(2)) // '321201.59' 
console.log(321201.585.toFixed(2)) // '321201.59'
console.log(321201.575.toFixed(2)) // '321201.58'
console.log(321201.565.toFixed(2)) // '321201.57'
console.log(321201.555.toFixed(2)) // '321201.55'
console.log(321201.545.toFixed(2)) // '321201.54'
console.log(321201.535.toFixed(2)) // '321201.53'
console.log(321201.525.toFixed(2)) // '321201.53'
console.log(321201.515.toFixed(2)) // '321201.52'
console.log(321201.505.toFixed(2)) // '321201.51'
console.log(321201.5951.toFixed(2)) // '321201.60'

上面的数据显示:321201.595 & 321201.555 & 321201.545 & 321201.535 没有进1,其他的都进了…

Math.round

网上说这个比较准确,round() 方法可把一个数字舍入为最接近的整数,我试了一下,也还是不准,举个🌰

console.log(Math.round(321201.595 * 100) / 100) // 321201.59
console.log(Math.round(321201.585 * 100) / 100) // 321201.59
console.log(Math.round(321201.575 * 100) / 100) // 321201.58
console.log(Math.round(321201.565 * 100) / 100) // 321201.57
console.log(Math.round(321201.555 * 100) / 100) // 321201.56
console.log(Math.round(321201.545 * 100) / 100) // 321201.55
console.log(Math.round(321201.535 * 100) / 100) // 321201.53
console.log(Math.round(321201.525 * 100) / 100) // 321201.53
console.log(Math.round(321201.515 * 100) / 100) // 321201.52
console.log(Math.round(321201.505 * 100) / 100) // 321201.51
console.log(Math.round(321201.5351 * 100) / 100) // 321201.6
console.log(Math.round(321201.5951 * 100) / 100) // 321201.6

上面的数据显示,321201.595 & 321201.535 没有进1,其他的都进了…

这是因为…321201.595 * 100 !== 32120159.5,而是32120159.499999996,这个问题是计算精度的问题;

解决

既然数字靠不住,那就处理字符串,因为项目的产品设计里只需要进行四舍五入保留两位数,所以为了快速修复问题,就针对两位数进行处理:

 function num2Fixed(num: number) {
    const numStr = num.toString();
    if (numStr.includes('.')) {
      const numArr = numStr.split('.');
      const decimalNum = parseInt(`${numArr[1][2]}`, 10);
      let numcArr = [];
      if (decimalNum >= 5) {
        numcArr = (num + 0.01).toString().split('.'); // 这里不放心的话可以用mathjs的方法
      } else {
        numcArr = num.toString().split('.');
      }
      return parseFloat(`${numcArr[0]}.${numcArr[1].substring(0, 2)}`);
    }
    return num;
  }

思路就是,把数字转成字符串,处理小数点后的第三位,如果大于等于5,就在原来的基础上 + 0.01,目前来看没有什么问题。

  1. 两个浮点数做乘法,精度丢失的情况

这个问题是在是无从下手,因为涉及到了加减乘除,无法用字符串再进行操作,找了一圈,还是选择用mathjs来解决(内心OS: 真不想用,用了它还得去解决打包依赖的问题,Vite我还不是很熟),具体操作如下:

import * as math from 'mathjs'; // 这里需要注意,新版的mathjs修改了import的方式
const { create, all } = math;
const $math = create(all, {
  epsilon: 1e-12,
  matrix: 'Matrix',
  number: 'BigNumber', // 可选值:number BigNumber
  precision: 64,
  predictable: false,
  randomSeed: null
});
/** Js 精度计算的方法 */
  function mathComputed(evalstr: string, need2fixed = true) {
    const num = Number($math.format($math.evaluate(evalstr)));
    if (need2fixed) { // 是否需要进行 四舍五入,保留两位小数的处理
      return num2Fixed(num);
    }
    return num;
  }

以上就是我遇到的问题,希望大家以后可以有效避开这些错误(谁项目里用了toFixed了,赶紧去检查一下吧!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
vite的server.proxy是一个配置项,用于设置代理。通过设置代理,可以在开发阶段将请求转发到其他服务器,以解决跨域问题。 具体用法: ```javascript // vite.config.js module.exports = { server: { proxy: { // 将本地 /api/xxx 代理到远端 '/api': 'https://remote-server.com', // 将本地 /foo/xxx 代理到远端 /bar/xxx '/foo': { target: 'https://remote-server.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/foo/, '/bar') }, // 将本地 /user/xxx 代理到远端,同时修改请求头和响应头 '/user': { target: 'https://remote-server.com', headers: { 'X-Proxy-Header': 'vite' }, onProxyReq: (proxyReq) => { proxyReq.setHeader('X-Proxy-Req-Header', 'vite') }, onProxyRes: (proxyRes) => { proxyRes.headers['X-Proxy-Res-Header'] = 'vite' } } } } } ``` 上述代码中,我们设置了三个代理规则,分别将本地 `/api`、`/foo`、`/user` 请求转发到远端服务器。 其中,`/api` 的代理目标是 `https://remote-server.com`,没有其他配置项;`/foo` 的代理目标也是 `https://remote-server.com`,同时使用了 `changeOrigin` 和 `rewrite` 两个配置项。`changeOrigin` 用于修改请求头中的 `Host` 字段,以防止目标服务器的反向代理出现问题;`rewrite` 用于修改请求路径,将 `/foo` 替换成 `/bar`。 最后,`/user` 的代理目标也是 `https://remote-server.com`,同时使用了 `headers`、`onProxyReq` 和 `onProxyRes` 三个配置项。`headers` 用于修改请求头中的自定义字段;`onProxyReq` 和 `onProxyRes` 用于修改请求和响应对象,可以添加、修改、删除请求头和响应头中的字段。 需要注意的是,vite的server.proxy只在开发阶段有效,打包后的代码不会包含这些配置项。如果需要在生产环境中使用代理,可以考虑使用其他工具,如nginx、Apache等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder HoMeTown

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值