4

Examples abound of methods to initiate a web (HTTP) request in Javascript. But, when I initiate a web request and the server return a blank response, Firefox at least throws an error:

XML Parsing Error: no root element found Location: http://example.com/service Line Number 1, Column 1: 1 service:1:1

I am using a function similar to:

function RequestGET(url) {
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.send();
}

In this particular case, the server has nothing to return and I expect that. So, how do I structure my client-side script to handle this response without throwing this error? Or, more generally, how can I handle a non-XML response properly?

2
  • I'd recommend using the JavaScript portion from this question, which essentially boils down to if (typeof window.ActiveXObject != 'undefined'). Commented Jun 6, 2017 at 22:42
  • If you want to play the modern game, fetch makes XHR easier in native JS Commented Jun 6, 2017 at 22:45

4 Answers 4

2

For probably a defensible reason, Firefox sets the default MIME type to XML (not sure if it's text/xml or application/xml). Thankfully, the XMLHttpRequest object has an overrideMimeType method, which I can use to set the MIME type to text/plain.

The following function works to ignore responses, blank or otherwise:

function RequestGET(url, callback) {
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    if (req.overrideMimeType)
        req.overrideMimeType("text/plain");
    req.send(null);
}
Sign up to request clarification or add additional context in comments.

1 Comment

The responseXML documentation helped me to arrive at this answer.
1

responseXML may === null

The XMLHttpRequest.responseXML property is a read-only value which returns a Document containing the HTML or XML retrieved by the request, or null if the request was unsuccessful, has not yet been sent, or if the retrieved data can't be correctly parsed as XML or HTML.

Something like the below will catch and handle the many possible returns we can expect.

var xhr = new XMLHttpRequest(),
    handleResponses = function( x ) {
        var s = x.status;
        if ( s < 400 ) {
            if ( s === 200 ) {
                var rXML = x.responseXML;
                if ( rXML !== null ) {
                    console.log( rXML );
                } else {
                    console.error( "Not XML" );
                    console.log( x.response );
                }
            } else {
                console.warn(
                    { 204: "No Content",
                      304: "Not Modified" // etc.
                    }[ s ] || "Nothingness..."
                );
            }
        } else {
            console.error(
                { 400: "Bad Request",
                  404: "Not Found" // etc.
                }[ s ] || "Oh snap!"
            );
        }
    };
xhr.open( "GET", "https://example.com/service", true );
xhr.addEventListener( "error", function() {
    // If this happens, the request effectively failed.
    console.error( "The internet is empty" );
}, false );
xhr.addEventListener( "readystatechange", function() {
    // Even if the request fails, this will happen.
    if ( xhr.readyState === 4 ) {
        handleResponses( xhr );
    }
}, false );
xhr.send();

2 Comments

Thank you for your link to the responseXML documentation, which helped me arrive at the answer.
YW. Documentation rocks \m/
0
req.onreadystatechange=function() {
    if (req.readyState===4 && req.status===200) {
        var response=req.responseText;
    }
};

This will capture the response into the "response" variable once the request has been completed

2 Comments

Including this part still throws the "XML Parsing Error", unfortunately.
Is this only when the server has no response? which line is it throwing it on?
0

Or, more generally, how can I handle a non-XML response properly?

I would give the Try...Catch a go.

try {
  // parse response data
}
catch(error){
 // handle parsing exception
}
finally{
 // buy me a beer
}

Perhaps this would work, but around which block would I wrap the exception handling?

function RequestGET(url) {
    var req = new XMLHttpRequest();

    // set callback for xhr state change events
    xhr.onreadystatechange  = function() {

        if (req.readyState === 4) {
            // request is completed

            if(req.status === 200) {
                // The request succeed!
                try {
                    // parse response data
                    var parser = new DOMParser();
                    var xmlDoc = parser.parseFromString(req.responseText,"text/xml");

                    // here your xml document object...
                    // > xmlDoc
                }
                catch(error){
                 // handle parsing exception
                }
                finally{
                 // buy me a beer
                }

            } else {
                // The request did not succeed!
            }
        }
    }

    req.open("GET", url, true);
    req.send();
}

2 Comments

Perhaps this would work, but around which block would I wrap the exception handling?
I extended my answer for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.