The origin of
Recently, when implementing A requirement, we need to access the interface of A third party. First, we call interface A, and there is A taskId in the data returned by interface A. Then, we use this taskId to request interface B to obtain the data we finally need.
Node is used at the back end, so the request-Promise package was used to request the third-party interface at the beginning. However, after obtaining the taskId returned by interface A, interface B responded with A system error after calling interface B. The simple code is as follows
const rp = require('request-promise')
const { taskId } = await rp('https://xxx.com/A')
const options = {
method: 'POST'.uri: 'https://xxx.com/B'.body: {
taskId
},
json: true
}
const result = await rp(options)
/ / {
// "errorcode": "40001",
// "message": "system error"
// "status": "failed"
// }
Copy the code
Then I use postman to request interface A, get A new taskId, and use the new taskId to request interface B, but the result is normal!
After I double-checked the code to make sure that the parameters in the request were in the correct format, I lost myself in endless meditation…
found
After several attempts, I found that the last two digits of the taskId obtained by node request were all 0 (1152921504735848700), while the taskId obtained by postman request was normal (1152921504735848759). I then do the following on the Node console
That’s 2 to the 53. 9007199254740992
Get the correct response data
Since the request-Promise package was originally used, the taskId was lost in accuracy, so node’s native HTTP module was used instead to send the request.
const req = https.request('https://xxx.com/A', (res) => {
res.on('data', (chunk) => {
// Since the response data is a JSON string, the 19-digit number is only part of the string, and the taskId is the correct number
console.log(`BODY: ${chunk}`);
});
res.on('end', () = > {console.log('No more data in response.'); })})Copy the code
Parse () will cause a loss of precision, which can be embarrassing Orz
If the interface were controlled, you could convert the 19-digit number to a string that would parse without error, but because it’s a third-party interface, you can’t change it. Well, the quickest solution would be to change languages
Final solution
Parse () : Node (); parse(); parse() : Node (); parse()
let result = '{" taskId ", 1152921504735848759, "status" : "CREATED", "progress" : 0.0, "success" : true}'
// json. parse(result) Does not fill 19 digits with double quotation marks.
/ / {
// taskId: 1152921504735848700,
// status: 'CREATED',
// progress: 0,
// success: true
// }
const taskId = result.match(/ [0-9] {19} /) [0] // The re gets the 19-digit value
result = result.replace(taskId,`"${taskId}"`) // add double quotes
const data = JSON.parse(result)
/ / {
// taskId: '1152921504735848759', // it is a string, so there is no loss of precision
// status: 'CREATED',
// progress: 0,
// success: true
// }
Copy the code
conclusion
I have been using Node for a while now, because it does not involve large numbers, so the numbers and ids are stored in string form, so I have not encountered this problem. This time unexpectedly met, have to say that JS in this aspect is really a little weak, later also tried to use Go, Python request, are able to correctly parse. ┑( ̄  ̄)┍ but node is very comfortable to use, ╮(╯▽╰)╭
Thanks!