如何从Axios POST请求返回18个字符串的响应

时间:2019-09-13 14:22:10

标签: javascript spring spring-boot vue.js axios

我正在尝试发出一个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。


  1. {数据:622056030329638900,状态:200,statusText:“”,标头:{…},配置:{…},…}
  2. config:{url:“ http://localhost:xxxx/persons”,方法:“ post”,数据:“ {” firstName”:“ daffy”,“ middleName”:“ woddle”,“ lastName”:“ duck”, “ homeEmail”:“ daffy@gmail.com”}“,标头:{…},transformRequest:Array(1),...}
  3. 数据:622056030329638900
  4. 标题:{content-length:“ 18”,内容类型:“ application / json; charset = UTF-8”}
  5. 请求:XMLHttpRequest
  6. onabort:ƒhandleAbort()
  7. onerror:ƒhandleError()
  8. onload:空
  9. onloadend:空
  10. onloadstart:空
  11. 正在进行中:null
  12. onreadystatechange:ƒhandleLoad()
  13. ontimeout:ƒhandleTimeout()
  14. readyState:4
  15. 响应:“ 622056030329638912”
  16. responseText:“ 622056030329638912”
  17. responseType:“”
  18. responseURL:“ http://localhost:xxxx/persons
  19. responseXML:空
  20. 状态:200
  21. statusText:“”
  22. 超时:0

预期结果:发送的所有18个字符均与接收到的字符匹配。 实际结果:前16个字符匹配,后两个字符为零。

3 个答案:

答案 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));