我正在尝试发出一个POST(添加)请求,该请求返回添加项的ID。 ID为18个字符串。只要字符串不超过16个字符,一切都可以正常工作。当长度为18个字符时,由于后两个字符默认为零,因此它们总是会损坏。
我将Vuejs用作前端,将SpringBoot用作后端。我知道Long的53位精度的javascript限制,这就是为什么我将String用作此ID的类型的原因。如果我尝试返回18位数字而不是18个字符串,我希望会发生这种情况。看来,尽管我返回了STRING类型,但Axios会自动将其转换为LONG,这会导致其损坏。我如何告诉Axios不要这样做? ##标题##谢谢。
=========后端restcontroller端点=============
@PostMapping("/persons")
public ResponseEntity<String> addPerson(@Valid @RequestBody Person person) {
String newPersonId = personService.addPerson(person);
return new ResponseEntity<>(newPersonId, HttpStatus.OK);
}
==============前端Axios POST调用==================
axios
.post("http://localhost:xxxx/persons", newPerson)
.then(response => {
console.log("Response from post is: " + response.data);
console.log(response);
newPerson.id = response.data;
})
.catch(error => console.log(error));
===========控制台输出:=============
以下行是我的前端Post调用中的console.log打印语句。这表明我收到的ID和最后两位数字为零。
帖子回复为:622056030329638900
请注意,response.data(下面的第3行)以900结尾,并且没有用引号引起来。如果您进一步阅读-response.request.response(第10和11行)以912结尾,这是正确的响应。我想我知道他们为什么不匹配(Axios将其转换为Long并由于53位精度限制而损坏),但我不明白为什么Axios首先将String转换为Long。
预期结果:发送的所有18个字符均与接收到的字符匹配。 实际结果:前16个字符匹配,后两个字符为零。
答案 0 :(得分:0)
该数字(622056030329638912
)对于JavaScript太大。看一下Number.MAX_SAFE_INTEGER
,值是9007199254740991
。在浏览器中,任何大于max safe integer的数字都不安全。
如果可以的话,将其作为字符串处理。如果必须使用response.data
,请让您的API返回字符串值。否则,使用responseText
应该没问题。
MAX_SAFE_INTEGER常数的值为9007199254740991(9,007,199,254,740,991或〜9四千万分之一)。该数字背后的原因是,JavaScript使用IEEE 754中指定的双精度浮点格式数字,并且只能安全地表示-(2 ^ 53-1)和2 ^ 53-1之间的数字。
在此上下文中,安全是指能够精确表示整数并正确比较它们的能力。例如,Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2将计算为true,这在数学上是不正确的。有关更多信息,请参见Number.isSafeInteger()。
这是一个示范:
console.log(Number.MAX_SAFE_INTEGER);
console.log(622056030329638922);
答案 1 :(得分:0)
尝试使用对象返回后端:
{value: "622056030329638900"}
这对我有用!
答案 2 :(得分:0)
问题最终归结为一个事实,例如“ 12334”之类的字符串不是有效的JSON字符串(而是有效的JSON数字)。 See this question
<script>
// 1233
alert(JSON.parse("1234")); // treated as a number
// SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
alert(JSON.parse("ABC"));
</script>
Axios默认以这种方式转换响应(它解析json):
transformResponse: [function transformResponse(data) {
/*eslint no-param-reassign:0*/
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) { /* Ignore */ }
}
return data;
}],
因此,如果您有以下选项:
一个:返回一个有效的Json字符串,例如:“ \” 622056030329638912 \“”(服务器端的JSON ENCODE)
alert(JSON.parse("\"622056030329638912\""));
二:在axios上禁用转换:
axios
.post("http://localhost:xxxx/persons", newPerson, {
transformResponse: function(response) {
// do not transform response at all...
return response;
}
})
.then(response => {
console.log("Response from post is: " + response.data);
console.log(response);
newPerson.id = response.data;
})
.catch(error => console.log(error));