SyntaxError: Unexpected token < in JSON at position 0
The most common reason for this error is attempting JSON to parse an HTML or XML response. The HTML and XML documents start with <, and JSON identifies it as an unparsable string. It is also possible that you are requesting an api that you don’t have permission to access. In that case, you expect a JSON, but the server returns a permission denial HTML.
This article demonstrates several JSON parsing errors with code examples.
Reason for Unexpected token < in JSON error
Listed below is a simple express.js route that generates an HTML response. It can be any api endpoint. The api generates the HTML response <p>This is an HTML response</p>.
router.post("/user/create/html", (request, response) => {
const reply = "<p>This is an HTML response</p>"
response.set('Content-Type', 'text/html');
response.send(reply);
});
Now let’s find out what happens when we try to parse this response with the JSON parser. The code makes a post request to the endpoint that produces an HTML response. Then it tries to JSON parse the response.
const serverHtmlResponse = await axios.post('/user/create/html')
console.log(serverHtmlResponse.headers["content-type"])
console.log(serverHtmlResponse.data)
console.log(typeof serverHtmlResponse.data)
const htmlResponse = JSON.parse(serverHtmlResponse.data)
Figure 1 : Unexpected token < in JSON error
Note that the endpoint’s response type is text/html and the content is <p>This is an HTML response</p>. The content is not parsable. Thats the reason you see the first character of the content < in the error message.
Reason for Unexpected token o in JSON at position 1
That error happens when we attempt to JSON parse an object.
The below express.js route produces a JSON object as the response.
router.post("/user/create/json", (request, response) => {
const reply = "This is a JSON object response"
response.json({response:reply});
});
The response of this endpoint is {response: ‘This is a JSON object response’}. That is not a JSON string. It is an object. The console.log(typeof serverJsonResponse.data) proves the api response is an object.
const serverJsonResponse = await axios.post('/user/create/json')
console.log(serverJsonResponse.headers["content-type"])
console.log(typeof serverJsonResponse.data)
console.log(serverJsonResponse.data)
const jsonResponse = JSON.parse(serverJsonResponse.data)
Figure 2 : Unexpected token o in JSON at position 1
Therefore, what happens here is JSON.parse(“[object Object]”)
and JSON complains about the character “o” it encountered first.
How to parse a JSON string correctly?
The JSON.parse() method accepts a string that correctly represents a JSON object. In other words, a string that is parsable into a JSON object.
Below is an express route that produces a JSON string like {“response”:”This is a JSON string response”}.
router.post("/user/create/jsonstring", (request, response) => {
const reply = `{"response":"This is a JSON string response"}`
response.json(reply)
});
The response is application/json, and the type is string. This type of response is parsable with JSON parser as long as the response string can represent a valid object.
const serverResponse = await axios.post('/user/create/jsonstring')
console.log(serverResponse.headers["content-type"])
console.log(typeof serverResponse.data)
console.log(serverResponse.data)
const jsonStringResponse = JSON.parse(serverResponse.data)