You expect xhr.responseText to contain a JSON encoded object. It looks like it actually contains a JSON encoded string (and that the JSON encoded string contains a JSON encoded object). Note the " characters around xhr.responseText when you console.log it.

That is to say: You have an object which has been encoded as JSON which has then been encoded as JSON again.

When you run JSON.parse(xhr.responseText), you decode the first layer of JSON encoding. This gives you a string of JSON that represents an object.