XMLHttpRequest in the browser
Here are a few issues with your code


If older browsers aren't a concern, you can just use fetch instead of XHR. It's built-in and uses promises.
HTTP 200 isn't the only "successful" response status. See https://en.wikipedia.org/wiki/List_of_HTTP_status_codes.
Status "0" is a generic network error, not just being offline. It can also be caused by the browser suppressing the request due to some restriction, an extension blocking the request, an insecure connection/invalid certificate.
Send an Accept header with application/json as value. This is because, while the server might support JSON, it might not respond with it by default.
The third argument of xhr.open is by default true. You may omit that third argument.
You can use readystatechange with addEventListener instead of the onreadystatechange property to assign your callback.