now_world
now_world

Reputation: 1096

NodeJS SyntaxError: Unexpected token in JSON at position 0

The body of the response from Authorize.net's sandbox API is:

{
  "messages": {
    "resultCode": "Error",
    "message": [
      {
        "code": "E00012",
        "text": "You have submitted a duplicate of Subscription 5777085. A duplicate subscription will not be created."
      }
    ]
  }
}

but when I go to parse it:

try {
   bodyObj = JSON.parse(body);
} catch (ex) {
   console.error(ex);
}

I get this error:

SyntaxError: Unexpected token in JSON at position 0

And this: console.log(response.headers['content-type']);

returns this: application/json; charset=utf-8

What am I doing wrong? I want to parse the JSON into a JS object.

Upvotes: 15

Views: 41134

Answers (2)

user12152456
user12152456

Reputation:

We had the same issue with JSON.parse() in a project we're working on. We're just using JSON.stringfy() and the object was working fine, but on the other platform where we received the data it had a similar error "Unexpected token in JSON at position 1".

Here's how we made it work:

  1. In NodeJs we encoded the stringified object using encodeURI() then sent it
  2. On the client side: decoded the string then used JSON.parse() on the decoded string

Analysis:

I tried to print the characters from the position, then replaced it with an empty string, then we realized it prints other weird characters even after replacing them. After that I realized it's an HTML code """ so instead of replacing it we went for encoding the string it and decoding.
We tried it on our case and it's working no problems

Upvotes: 3

randomuser5215
randomuser5215

Reputation: 527

Actually you didn't see it, but there was a invisible unicode character, specifically the byte order mark at the beginning of the JSON.
Since the byte order mark is not a valid JSON character, JSON.parse rejected it.
byte order mark image
To remove, use the following code.

function removeByteOrderMark(str){
    return str.replace(/^\ufeff/g,"")
}
// OR (faster),
let removeByteOrderMark = a=>a[0]=="\ufeff"?a.slice(1):a

Upvotes: 19

Related Questions