DEV Community

shujaat ali
shujaat ali

Posted on

XHR not send to server on 'beforeunload' event in IE

This is my first post ever on any blog/site i am not a good writer. I am junior ASP.NET software engineer recently i am working in React for front end development.

Yesterday was writing a function in JavaScript for on window closed. function responsibility was to send xhr call to server.

Here is my source code.

// binding beforunload event

 componentDidMount() {
      if (window.addEventListener) {
        window.addEventListener('beforeunload', this.onUnload, false);
      } else if (window.attachEvent) {
        window.attachEvent('onbeforeunload', this.onUnload);
      }
    }

// call api function 'unlock'
onUnload() {
      unlock();
    }


// api 
export function unlock(Id) {
  return axios
    .get(UNLOCK(Id))
    .then((data) => data);
}
Enter fullscreen mode Exit fullscreen mode

It was working fine for chrome but it was not working for IE.
I spend a lot of time to debug this issue but did not succeed. after that one of my colleague recommend me to send an sync call to the server because of asynchronous browser did not wait for response. after spend a lot time of arguing with him i implement and it works.

After change async to sync

export function unlock(Id) {
  // use jQuery ajax call becaus axios does not provide {async: false} option
  window.jQuery.ajax({
    type: 'GET',
    url: UNLOCK(Id),
    async: false,
    success(data) {
      //code 
    },
  });
}
Enter fullscreen mode Exit fullscreen mode

Discussion

My understanding is when unlock function calls on window close. function should send xhr request to server after that browser tab should be closed.
In my case i don't need the response of xhr call.

Question: why unlock function was not sending the call to the server?

Top comments (3)

Collapse
 
tom profile image
tom

I think your colleague was more-or-less right.

The HTML Standard says that beforeunload is there "in case the page would like to show a warning prompt".

Specifically, you can specify a message that the browser should show to the user before the page is closed just in case they didn't mean it:

window.addEventListener("beforeunload", function (event) {
  event.returnValue = "Don't leave! We only just met.";
});
Enter fullscreen mode Exit fullscreen mode

It isn't meant for doing (possibly long-running) asynchronous tasks like sending network requests.

The HTML5 spec has more detail, specifically around unloading documents.

It undergoes a complex set of tasks as the page unloads, including some network request cleanup, but it does allow for you to start an asynchronous network request in the beforeunload event handler — see item 4.

That said, I can't find anything specific about in-flight network request cleanup.

It seems likely that your requests works in Chrome because it takes a while to cleanup a document, but IE is faster (or just kills networks requests straight away).

Or, possibly, Chrome is reusing the document (yep, that's a thing) and allowing the request to continue, where IE is not.

This probably also has something todo with tasks and microtasks which is totally out of scope for this reply. The linked post is excellent if you'd like to know more.

All that said, beforeunload isn't the right place to be sending network requests, synchronous or not.


Bonus fact: we needed something like for TweetDeck.

To avoid the network request issue, we write the data we were planning to send into local storage, synchronously, in the beforeunload handler. Then, when the user opens TweetDeck again, we read the data back out of storage and send the request.

This only works for a specific kind of request — in our case, some code instrumentation — but it might work for you too!

Collapse
 
teodor_asa profile image
WARNINNG:

Hi there, it is not working because Chrome already restrict such functionality: chromestatus.com/feature/466484305...

Collapse
 
goshishah profile image
shujaat ali

@erildo Shuli if you don't know the answer please don't comment :) Thanks.