Execute a http request before page reload

Viewed 374

I'm working on a React application, and I want to destroy the session when the user tries to close the page, or reloads the page.

Things I tried:

  • window.onbeforeunload = () => true : This provides a default prompt with custom message possible.
  • Prompt (react-router) : didn't capture page reload
  • via eventListener in useEffect

useEffect(() => {

  window.addEventListener("beforeunload", function(evt) {
    // Cancel the event (if necessary)
    evt.preventDefault();
   
    axios.get('url/destroy').then(res=>  evt.returnValue = '';)
});
  }, []);

Issue being faced: The request gets cancelled. Issue image for reference

I tried to add evt.returnValue = '' inside a timeout with response of http call. But it didn't work too.

Any workarounds for the same or to achieve the same i.e making a http call on page reload/close.

Thanks in advance.

Update 1:

 useEffect(() => {
    window.addEventListener("beforeunload", (e) =>
      alertUser(e, cookies.get("env"))
    );
   
  }, []);
    const alertUser = async (e, tempBool) => {
    e.preventDefault();
    if (tempBool) {
      let blob = new Blob(
        [
          JSON.stringify({
            data: "data",
          }),
        ],
        { type: "application/json" }
      );
      navigator.sendBeacon(
        "ur/destroy_session",
        blob
      );
      e.returnValue = "";
    } else {
      e.returnValue = "";
    }
  };

I want to send request based on certain cookie value. In this case, the request is getting called with type=ping on pressing reload and type=xhr on cancel

http How to only allow http call on Reload?

1 Answers

Wondering if service workers could come in useful here, as they run in a background thread. Haven't tried this but worth a shot.

navigator.serviceWorker.register('serviceWorker.js');


window.onunload = function() {
  navigator.serviceWorker.controller.postMessage({
    type: 'closeWindow'
  });
};

self.onmessage = function(event) {
  if (event.data.type === 'closeWindow') {
  
  }
}
Related