Identificar entre acciones de actualización y cierre del navegador

Resuelto ashish bhatt asked hace 15 años • 0 respuestas

Cuando actualizamos la página (F5 o icono en el navegador), primero se activará el evento ONUNLOAD. Cuando cerramos el navegador (X en el icono superior derecho), se activará el evento ONUNLOAD. Ahora, cuando se activa el evento ONUNLOAD, no hay forma de distinguir entre actualizar la página o cerrar el navegador. Si tienes alguna solución entonces dímelo.

ashish bhatt avatar Feb 20 '09 17:02 ashish bhatt
Aceptado

Hay una solucion.

Quería desconectar al usuario en el servidor cuando se cerraba la pestaña o la ventana del navegador, pero no cuando se recargaba la página (es posible que desee diferenciar los eventos de recarga/cierre para un propósito diferente, pero puede beneficiarse de mi solución). Terminé con el siguiente proceso, basado en el almacenamiento local de HTML5 y la comunicación AJAX cliente/servidor:

  1. en su página, agregue un onunloadal windowsiguiente controlador (pseudo-javascript):

    function myUnload(event) {
        if (window.localStorage) {
            // flag the page as being unloading
            window.localStorage['myUnloadEventFlag']=new Date().getTime();
        }
    
        // notify the server that we want to disconnect the user in a few seconds (I used 5 seconds)
        askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call
    }
    
  2. en su página, agregue un onloadal bodysiguiente controlador (pseudo-javascript):

    function myLoad(event) {
        if (window.localStorage) {
            var t0 = Number(window.localStorage['myUnloadEventFlag']);
            if (isNaN(t0)) t0=0;
            var t1=new Date().getTime();
            var duration=t1-t0;
            if (duration<10*1000) {
                // less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request)
                askServerToCancelDisconnectionRequest(); // asynchronous AJAX call
            } else {
                // last unload event was for a tab/window close => do whatever you want (I do nothing here)
            }
        }
    } 
    
  3. en el servidor, recopile las solicitudes de desconexión en una lista y configure un hilo de temporizador que inspeccione la lista a intervalos regulares (yo usé cada 20 segundos). Una vez que se agota el tiempo de espera de la solicitud de desconexión (es decir, pasan los 5 segundos), desconecte al usuario del servidor. Si mientras tanto se recibe una cancelación de solicitud de desconexión, la solicitud de desconexión correspondiente se elimina de la lista, de modo que el usuario no será desconectado.

Este enfoque también es aplicable si desea diferenciar entre el evento de cierre de pestaña/ventana y los enlaces seguidos o el formulario enviado. Solo necesita colocar los dos controladores de eventos en cada página que contenga enlaces y formularios y en cada página de inicio de enlace/formulario.

Tenga en cuenta que uso el unloadevento en lugar del beforeUnloadevento para administrar correctamente los enlaces a los archivos adjuntos: cuando un usuario hace clic en un enlace a un archivo adjunto (por ejemplo, un archivo PDF), beforeUnloadse envía el evento, luego se genera una ventana emergente para abrir/guardar y nada más (el navegador no cambia la página mostrada y no envía el unloadevento). Si estuviera usando el beforeUnloadevento (como lo hice antes), habría detectado un cambio de página cuando no hay ninguno.

Este enfoque se limita a los navegadores que admiten almacenamiento local HTML5, por lo que probablemente utilizaría enfoques específicos para navegadores antiguos como MSIE7.

Otros enfoques basados ​​en event.clientYno son confiables porque este valor es negativo al hacer clic en los botones de recarga o cierre de pestaña/ventana, y positivo cuando se usan atajos de teclado para recargar (por ejemplo, F5, Ctrl-R, ...) y cerrar la ventana ( por ejemplo, Alt-F4). Confiar en la posición del evento X tampoco es confiable porque los botones no están ubicados en la misma posición en todos los navegadores (por ejemplo, el botón de cerrar a la izquierda).

Julien Kronegg avatar Dec 17 '2012 15:12 Julien Kronegg

Tal vez alguien todavía esté buscando una respuesta...

¡ Puedes usar SessionStorage para eso! SessionStorage no se borra cuando se recarga la página sino cuando se cierra. Básicamente, puede establecer un par clave/valor cuando se carga la página, pero antes de eso verifica si el par clave/valor existe. Si existe significa que la página fue recargada, si no, significa que el usuario abrió la página por primera vez o en una pestaña nueva.

if (sessionStorage.getItem('reloaded') != null) {
    console.log('page was reloaded');
} else {
    console.log('page was not reloaded');
}

sessionStorage.setItem('reloaded', 'yes');

De esta manera puede hacerlo doStuff()con el onunloadevento (el usuario abandona la página) y otherStuff()si el par clave/valor está configurado (el usuario recargó la página).

Mointy avatar Aug 18 '2020 23:08 Mointy

Desafortunadamente, inspeccionar el valor clientY/ pageYdel evento, como lo sugieren algunas de las respuestas aquí, no es una forma confiable de determinar si el unloadevento se activa como consecuencia del cierre de la página por parte del usuario.

La razón por la que clientY/ pageYes negativo cuando hace clic en el botón de cerrar del navegador es porque el botón de cerrar está ubicado encima de la parte superior del documento (es decir, encima del píxel 0), pero también lo está el botón de recarga, lo que significa que hacer clic en el botón de recarga también resultará en un resultado negativo. valor por clientY/ pageY.

Seguir el camino de inspeccionar la coordenada x del evento también es problemático porque el botón de cerrar del navegador no siempre está en el lado derecho de la ventana (por ejemplo, está a la izquierda en OS X) y porque una ventana se puede cerrar cerrando su pestaña o mediante el teclado.

Walter Rumsby avatar Oct 05 '2009 00:10 Walter Rumsby

Hoy tuve el mismo problema y encontré una posible solución que quiero compartir con ustedes.

Mientras pensaba en lo que podría ayudar a discernir entre actualizar y cerrar, me vinieron a la mente las cookies. Recuerdo que configurar una cookie sin una fecha de vencimiento explícita la hace disponible solo para la sesión actual. Y una sesión actual es claramente válida hasta que se cierra el navegador. Esto no incluye cerrar una pestaña, pero mi problema era sobre la autenticación del usuario y no quería cerrar la sesión del usuario solo por haber cerrado una pestaña (creo que es el mismo enfoque que la ASPXAUTHcookie de ASP.NET).

Entonces, puse una cookie simple en la document.cookiescolección cuando el usuario inició sesión y la verifiqué al cargar la página: si la cookie todavía estaba allí, fue una actualización o una pestaña reabierta y los datos del usuario se mantuvieron, si la cookie no estaba presente, la sesión había caducado, por lo que el usuario Se borraron los datos (igual que un cierre de sesión explícito).

¡Espero que este enfoque pueda ser útil para alguien más!

Alessandro avatar May 12 '2017 08:05 Alessandro