Ad

XMLHttpRequest Onloadend Event Not Running On Error

- 1 answer

Is there an event that'll run whether on success or error with Node.js's XMLHttpRequest module? According to the docs, the onloadend event should trigger both on error and success, but it only runs on success. For example:

var XMLHttpRequest = require( 'xmlhttprequest' ).XMLHttpRequest;

var url = 'https://www.example-bad-url.com/json.php';

var xhr = new XMLHttpRequest();

xhr.open( 'GET', url );
xhr.send();

xhr.onloadend = function() {
    // This should get logged, but it doesn't.
    console.log( 'The request has completed, whether successfully or unsuccessfully.' );
}

In the above script, onloadend doesn't run, why? The URL doesn't exist, so it should trigger onloadend as an error and log "The request has completed..." but the callback function never runs, why?

Ad

Answer

The xmlhttprequest library for node.js does not fully implement the spec correctly.

If we dig into the code on github, we see the following line of code:

  if (self.readyState === self.DONE && !errorFlag) {
    self.dispatchEvent("load");
    // @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
    self.dispatchEvent("loadend");
  }

So the load and the loadend event handlers are only triggered when there is NOT an error, consistent with our observations where

xhr.onloadend = function() {
    // This should get logged, but it doesn't.
    console.log( 'The request has completed.' );
};

will only log when the event succeeded.

My advice would be to trigger the event manually in the .onerror() handler, which does work. Keep in mind that this is a 3rd party node.js module, not a native one.

Personally I just wrote a small wrapper around xmlhttprequest that mimics the .fetch() interface. The node.js version uses the native node.js http library and the client side version uses xmlhttprequest.

That way I can use the same .fetch() API for both front end and back end code, and just let the system decide if it'll use native fetch, xmlhttp powered fetch, or http powered fetch.

Ad
source: stackoverflow.com
Ad