uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况

1、使用 json-bigint,失败

2、使用 config 里的 getTask,失败

3、修改 dataType,成功

原因:

  • 通过ajax请求回来的数据在response和preview两种状态显示的是不同的。
  • response中的看到的数据格式其实是字符串(ajax请求回来的数据本质上是字符串格式),preview其实是用了JSON.Parse(字符串) 给我们做美化(格式化),这个转换过程中,一般不会出问题,但是,如涉及大数(一个很大的整数,超过了javascript最大的处理能力),就会产生转换精度丢失。
  • JavaScript 能够准确表示的整数范围在-2^532^53之间(不含两个端点),超过这个范围,无法精确表示这个值,这使得 JavaScript 不适合进行科学和金融方面的精确计算。 

 uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况_第1张图片

解决方法:

由于uView使用的是http请求插件是 luch-request(luch-request),去看了源码,发现:

uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况_第2张图片

1、因此需要将 dataType 修改为 string,首先去 uview-ui --> libs --> luch-request --> adapters --> index.js下注释掉下图这行,如果不注释掉,即使在 request.js 中将 dataType 修改为 string,还是会进入这行,还是会进行 parse 转换。

uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况_第3张图片

 2、然后在 requent.js下:

 uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况_第4张图片

 3、在响应拦截里对响应回来的数据进行处理uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况_第5张图片

成功转换: 

 uniapp使用uView框架,后端传16位数以上时出现精度缺失的情况_第6张图片

 request.js全部代码:

// 此vm参数为页面的实例,可以通过它引用vuex中的变量
module.exports = (vm) => {
	// 初始化请求配置
	uni.$u.http.setConfig((config) => {
		/* config 为默认全局配置*/
		config.baseURL = 'xxxxxx'; /* 根域名 */
		config.dataType = 'string';
		return config
	})
	// 请求拦截
	uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作
		// 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
		config.data = config.data || {}
		// 根据custom参数中配置的是否需要token,添加对应的请求头
		if(config?.custom?.auth) {
			// 可以在此通过vm引用vuex中的变量,具体值在vm.$store.state中
			const token = uni.getStorageSync('token');
			config.header.Authorization = token
		}
		return config
	}, config => { // 可使用async await 做异步操作
		return Promise.reject(config)
	})
	// 响应拦截
	uni.$u.http.interceptors.response.use((response) => {
		/* 对响应成功做点什么 可使用async await 做异步操作*/
		let data = response.data // 注意这个原来是 const ,因为后面要修改,所以改成 let

		var json = data.replace(/:s*([0-9]{15,})s*(,?)/g, ': "$1" $2')
		// 1.根据后端返回的数据调用一次或者两次replace替换

		var json1 = json.replace(/:s*([0-9]{15,})s*(,?)/g, ': "$1" $2')

		// 2.手动转换回json数据即可
		var trueData = JSON.parse(json1);

		// console.log('有问题的数据',response.data) //有问题的数据,长字段被四舍五入的数据
		console.log('正确的数据',trueData.data) //实际上正确的数据
		data = trueData
		
		// 自定义参数
		const custom = response.config?.custom
		if (data.code !== 200) {
			if (data.code == 401) { // token 失效
				uni.reLaunch({
					url: "/pages/login/login"
				})
			}
			// 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
			if (custom.toast !== false) {
				uni.$u.toast(data.msg)
			}

			// 如果需要catch返回,则进行reject
			if (custom?.catch) {
				return Promise.reject(data)
			} else {
				// 否则返回一个pending中的promise,请求不会进入catch中
				return new Promise(() => {})
			}
		}
		return data.data === undefined ? {} : data.data
	}, (response) => {
		// 对响应错误做点什么 (statusCode !== 200)
		return Promise.reject(response)
	})
}

你可能感兴趣的:(uni-app)