Warm tip: This article is reproduced from serverfault.com, please click

Run function only when tab/window is actually closed

发布于 2020-11-25 13:19:32

I am trying to send a get request to express from a react client when the user closes the tab.

I actually managed it with this, but with no confirmation:

window.addEventListener('beforeunload', async () => await axios('/delete');

If I try to make use of the proper confirmation message:

window.addEventListener('beforeunload', (e) => {
  e.preventDefault();
  e.returnValue = '';
  return true;
})

I do get the confirmation message, but I have no way to capture the response to run the function only if leave is clicked.

I saw a lot of responses about this but they are very old and dont seem to work on the latest browsers.

Questioner
Álvaro
Viewed
0
Álvaro 2020-11-28 23:13:24

In the end I did something really convoluted. But it works for me.

On the React front end, I make the call to delete as soon as the event is triggered. Since I can not detect if the user clicks to stay, I do setTimeout and give it 1s on the front end.

useEffect(() => window.addEventListener('beforeunload', async (e) => {
  e.preventDefault()
  e.returnValue = ''
  await axios.post('/api/delete', { stay: false })
  setTimeout(async () => {
   await axios.post('/api/delete', { stay: true })
  }, 1000)
 }), [])

And on the Express back end, I wait 2s for a cancellation to occur, if not then go ahead and delete.

let timer

app.post('/api/delete', (req, res) => {
  if (req.body.stay) {
    clearTimeout(timer)
  } else {
    clearTimeout(timer)
    timer = setTimeout(() => console.log('delete a file here'), 2000)
  }
  res.end()
})

If anyone can come up with something better I will accept that answer.