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?

palswim
  • 11,856
  • 6
  • 53
  • 77
  • I'd recommend using the JavaScript portion from [**this question**](https://stackoverflow.com/q/2212068/2341603), which essentially boils down to `if (typeof window.ActiveXObject != 'undefined')`. – Obsidian Age Jun 06 '17 at 22:42
  • If you want to play the modern game, `fetch` makes XHR easier in native JS – Sterling Archer Jun 06 '17 at 22:45

4 Answers4

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);
}
palswim
  • 11,856
  • 6
  • 53
  • 77
  • The [responseXML](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML) documentation helped me to arrive at this answer. – palswim Jun 07 '17 at 00:07
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();
Fred Gandt
  • 4,217
  • 2
  • 33
  • 41
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

Chris Thornton
  • 162
  • 2
  • 12
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();
}