这得从axios中得默认值说起:
Axios 的 transformResponse
axios
在接收到服务器的响应后,会通过一系列的转换函数(transformResponse
)来处理响应数据,使其适合在应用程序中使用。默认情况下,axios
的transformResponse
包含以下步骤:
- 解析 JSON 数据:使用
JSON.parse
将响应的 JSON 字符串转换为 JavaScript 对象。 - 转换数据:根据响应的
Content-Type
,可能进行其他转换(如将 XML 转换为对象)。 - 返回数据:最终返回处理后的数据供应用程序使用。
默认的 transformResponse
javascript">// node_modules/axios/lib/defaults.js
const defaults = {// 其他默认配置...transformResponse: [function transformResponse(data) {// 对 data 进行任意转换处理if (typeof data === 'string') {try {data = JSON.parse(data);} catch (e) { /* 忽略解析错误 */ }}return data;}],// 其他默认配置...
};
在这个过程中,
JSON.parse
将 JSON 字符串转换为 JavaScript 对象。然而,JavaScript 的Number
类型在处理某些数字时会自动去除不必要的尾随零,例如将12.00
转换为12
。
为什么 JSON.parse
会舍去小数点后的零?
是因为 JSON.parse
将数字字符串解析为 JavaScript 的 Number
类型。在 JavaScript 中,12.00
和 12
被认为是相等的数值,因此 JSON.parse
会自动优化表示方式,去掉不必要的尾随零。这是 JavaScript 的预期行为,但在某些需要保留特定小数位数的场景下,这可能会导致问题。
解决方案-------------------------------------
1. 后端返回字符串类型的数据
最直接的方法是让后端在返回JSON数据时,将需要保留小数位数的数字字段作为字符串返回。这样,前端接收到的数据将保留原始的小数点后零。
后端示例(以Java为例):
java">public class ResponseData {@JsonFormat(shape = JsonFormat.Shape.STRING)private String number;// getters and setters
}
返回的JSON:
javascript">{"number": "12.00"
}
前端处理:
javascript">axios.get('/api/your-api').then(response => {const numberString = response.data.number; // "12.00"const number = parseFloat(numberString); // 如果需要数值类型,可以转换const formattedNumber = number.toFixed(2); // "12.00"
});
2. 自定义transformResponse
如果无法修改后端返回的数据格式,可以在axios
的配置中自定义transformResponse
,在数据被解析为JavaScript对象之前,对特定字段进行处理,确保数字以字符串形式保留小数点后的零。
示例代码:
javascript">import axios from 'axios';const axiosInstance = axios.create({transformResponse: [function (data) {let parsedData;try {parsedData = JSON.parse(data, (key, value) => {if (typeof value === 'number' && Number.isFinite(value)) {return value.toFixed(2);}return value;});} catch (e) {return data;}return parsedData;}],
});axiosInstance.get('/api/your-api').then(response => {console.log(response.data); // 数字字段将以字符串形式保留两位小数
});
3. 在前端手动处理数字格式
如果后端返回的数字是数值类型,且你只需要在前端展示时保留小数点后的零,可以在渲染时进行格式化,而不改变原始数据。
示例代码(Vue.js):
<template><div>格式化后的数字: {{ formattedNumber }}</div>
</template><script>
export default {data() {return {number: 12.00 // 假设这是从后端获取的数字};},computed: {formattedNumber() {return this.number.toFixed(2); // "12.00"}}
};
</script>
4. 使用字符串处理库
如果需要更复杂的数字格式化,可以使用第三方库如numeral.js
或accounting.js
来处理数字格式。
使用numeral.js
的示例:
javascript">npm install numeral
javascript">import axios from 'axios';
import numeral from 'numeral';axios.get('/api/your-api').then(response => {const number = response.data.number; // 假设是数值类型 12const formattedNumber = numeral(number).format('0.00'); // "12.00"console.log(formattedNumber);
});
总结-------------------------------------------------------
为了避免前后端交互中数字格式的问题,最佳实践是:
- 后端返回字符串类型的数据,明确保留小数点后的零。 -----首选
- 自定义
transformResponse
,在数据解析阶段对特定字段进行处理。 - 前端进行格式化,在展示时根据需要格式化数字。