Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript, browsers, window close - send an AJAX request or run a script on window closing

I'm trying to find out when a user left a specified page. There is no problem finding out when he used a link inside the page to navigate away but I kind of need to mark up something like when he closed the window or typed another URL and pressed enter. The second one is not so important but the first one is. So here is the question:

How can I see when a user closed my page (capture window.close event), and then... doesn't really matter (I need to send an AJAX request, but if I can get it to run an alert, I can do the rest).

like image 628
zozo Avatar asked May 28 '11 14:05

zozo


People also ask

What is the method for close window in JavaScript?

close() The Window. close() method closes the current window, or the window on which it was called. This method can only be called on windows that were opened by a script using the Window.

Can JavaScript close a window?

JavaScript does not allow one to close a window opened by the user, using the window. close() method due to security issues. However, we can close a window by using a workaround. The approach to be followed is by opening the current URL using JavaScript so that it could be closed with a script.

How do you fix Scripts may close only the windows that were opened by it?

Scripts may close only the windows that were opened by it. A workaround now is redirect user to another page rather than close the window, you could redirect user to a notification page to show "The items has been closed successfully" using window. location. href="PageUrl".

Can I do AJAX call in JavaScript?

Ajax is a programming concept. Below are some ways to make Ajax call in JavaScript. Approach 1: In this approach, we will use the XMLHttpRequest object to make Ajax call. The XMLHttpRequest() method which create XMLHttpRequest object which is used to make request with server.


1 Answers

Updated 2021

TL;DR

Beacon API is the solution to this issue (on almost every browser).

A beacon request is supposed to complete even if the user exits the page.

When should you trigger your Beacon request ?

This will depend on your usecase. If you are looking to catch any user exit, visibilitychange (not unload) is the last event reliably observable by developers in modern browsers.

NB: As long as implementation of visibilitychange is not consistent across browsers, you can detect it via the lifecycle.js library.

# lifecycle.js (1K) for cross-browser compatibility # https://github.com/GoogleChromeLabs/page-lifecycle  <script defer src="/path/to/lifecycle.js"></script> <script defer> lifecycle.addEventListener('statechange', function(event) {    if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {     var url = "https://example.com/foo";     var data = "bar";      navigator.sendBeacon(url, data);   } }); </script> 

Details

Beacon requests are supposed to run to completion even if the user leaves the page - switches to another app, etc - without blocking user workflow.

Under the hood, it sends a POST request along with the user credentials (cookies), subject to CORS restrictions.

    var url = "https://example.com/foo";     var data = "bar";      navigator.sendBeacon(url, data); 

The question is when to send your Beacon request. Especially if you want to wait until the last moment to send session info, app state, analytics, etc.

It used to be common practice to send it during the unload event, but changes to page lifecycle management - driven by mobile UX - killed this approach. Today, most mobile workflows (switching to new tab, switching to the homescreen, switching to another app...) do not trigger the unload event.

If you want to do things when a user exits your app/page, it is now recommended to use the visibilitychange event and check for transitioning from passive to hidden state.

document.addEventListener('visibilitychange', function() {          if (document.visibilityState == 'hidden') {           // send beacon request   }  }); 

The transition to hidden is often the last state change that's reliably observable by developers (this is especially true on mobile, as users can close tabs or the browser app itself, and the beforeunload, pagehide, and unload events are not fired in those cases).

This means you should treat the hidden state as the likely end to the user's session. In other words, persist any unsaved application state and send any unsent analytics data.

Details of the Page lifecyle API are explained in this article.

However, implementation of the visibilitychange event, as well as the Page lifecycle API is not consistent across browsers.

Until browser implementation catches up, using the lifecycle.js library and page lifecycle best practices seems like a good solution.

# lifecycle.js (1K) for cross-browser compatibility # https://github.com/GoogleChromeLabs/page-lifecycle  <script defer src="/path/to/lifecycle.js"></script> <script defer> lifecycle.addEventListener('statechange', function(event) {    if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {     var url = "https://example.com/foo";     var data = "bar";      navigator.sendBeacon(url, data);   } }); </script> 

For more numbers about the reliability of vanilla page lifecycle events (without lifecycle.js), there is also this study.

Adblockers

Adblockers seem to have options that block sendBeacon requests.

Cross site requests

Beacon requests are POST requests that include cookies and are subject to CORS spec. More info.

like image 62
Baishu Avatar answered Oct 13 '22 01:10

Baishu