ventana funcion evitar ejecutar cerrar automaticamente abrir javascript browser javascript-events window

funcion - evitar cerrar ventana javascript



JavaScript, navegadores, ventana cerrada: envĂ­e una solicitud AJAX o ejecute un script al cerrar la ventana (6)

Estoy tratando de averiguar cuándo un usuario salió de una página específica. No hay problema para descubrir cuándo usó un enlace dentro de la página para navegar, pero necesito marcar algo así como cuando cerró la ventana o escribió otra URL y presionó enter. El segundo no es tan importante, pero el primero sí lo es. Así que aquí está la cuestión:

¿Cómo puedo ver cuándo un usuario cerró mi página (capturar evento window.close), y luego ... realmente no importa (tengo que enviar una solicitud AJAX, pero si puedo hacer que ejecute una alerta, puedo Haz el resto).


1) Si está buscando una forma de trabajar en todos los navegadores, la forma más segura es enviar un AJAX sincrónico al servidor. No es un buen método, pero al menos asegúrese de no enviar demasiados datos al servidor, y el servidor es rápido.

2) También puede usar una solicitud AJAX asíncrona y usar la función ignore_user_abort en el servidor (si está usando PHP). Sin embargo, ignore_user_abort depende mucho de la configuración del servidor. Asegúrate de probarlo bien.

3) Para los navegadores modernos, no debe enviar una solicitud AJAX. Debe usar el nuevo método navigator.sendBeacon para enviar datos al servidor de forma asíncrona y sin bloquear la carga de la página siguiente. Como desea enviar datos al servidor antes de que el usuario se salga de la página, puede usar este método en un controlador de eventos de descarga .

$(window).on(''unload'', function() { var fd = new FormData(); fd.append(''ajax_data'', 22); navigator.sendBeacon(''ajax.php'', fd); });

También parece haber un polyfill para sendBeacon . Recurre a enviar un AJAX síncrono si el método no está disponible de forma nativa.

IMPORTANTE PARA DISPOSITIVOS MÓVILES: tenga en cuenta que no se garantiza que el controlador de eventos de descarga se active para móviles . Pero el evento visibilitychange está garantizado para ser disparado. Por lo tanto, para dispositivos móviles, su código de recopilación de datos puede necesitar un poco de ajuste.

Puede consultar el artículo de mi blog para la implementación del código de las 3 formas.


Utilizar:

<body onUnload="javascript:">

Debería capturar todo excepto apagar el programa del navegador.


Hay eventos javascript de unload y beforeunload unload , pero estos no son confiables para una solicitud Ajax (no se garantiza que una solicitud iniciada en uno de estos eventos llegue al servidor).

Por lo tanto, hacer esto no es recomendable, y debes buscar una alternativa.

Si definitivamente lo necesita, considere una solución estilo "ping". Envíe una solicitud cada minuto básicamente diciéndole al servidor "Todavía estoy aquí". Luego, si el servidor no recibe dicha solicitud durante más de dos minutos (tiene que tener en cuenta las latencias, etc.), considera que el cliente no está conectado.

Otra solución sería utilizar la unload o beforeunload unload para hacer una solicitud de Sjax (JavaScript síncrono y XML), pero esto no se recomienda por completo. Hacer esto básicamente congelará el navegador del usuario hasta que se complete la solicitud, lo cual no les gustará (incluso si la solicitud toma poco tiempo).


También quería lograr la misma funcionalidad y encontré esta respuesta de Felix ( no se garantiza que una solicitud iniciada en uno de estos eventos llegue al servidor ).

Para que la solicitud llegue al servidor, probamos el siguiente código: -

onbeforeunload = function() { //Your code goes here. return ""; }

Estamos utilizando el navegador IE y ahora, cuando el usuario cierra el navegador, recibe el diálogo de confirmación debido a la return ""; y espera la confirmación del usuario y este tiempo de espera hace que la solicitud llegue al servidor.


Estoy de acuerdo con la idea de Felix y he resuelto mi problema con esa solución y ahora quiero borrar la solución de Server Side:

1. Enviar una solicitud del lado del cliente al servidor

2. ahorre tiempo de la última solicitud recibida en una variable

3.verifique la hora del servidor y compárela por la variable de la última solicitud recibida

4. si el resultado es más de lo esperado, comience a ejecutar el código que desea ejecutar cuando Windows se cierre ...


La respuesta seleccionada es correcta, no se puede garantizar que el navegador envíe la solicitud xhr, pero dependiendo del navegador, se puede enviar una solicitud de manera confiable en la pestaña o ventana cerrada.

Normalmente, el navegador se cierra antes de que xhr.send () se ejecute realmente. Chrome y edge parecen esperar que el bucle de eventos javascript se vacíe antes de cerrar la ventana. También activan la solicitud xhr en un hilo diferente al bucle de evento javascript. Esto significa que si puede mantener el bucle de eventos lleno el tiempo suficiente, el xhr disparará con éxito. Por ejemplo, probé enviando una solicitud xhr, luego contando a 100,000,000. Esto funcionó de manera muy consistente tanto en Chrome como en Edge para mí. Si está usando angularjs, envolver su llamada a $ http in $ apply logra lo mismo.

IE parece ser un poco diferente. No creo que IE espere que el bucle de eventos se vacíe o que el marco de pila actual se vacíe. Si bien ocasionalmente enviará correctamente una solicitud, lo que parece suceder con más frecuencia (80% -90% de las veces) es que IE cerrará la ventana o pestaña antes de que la solicitud xhr se haya ejecutado por completo, lo que dará como resultado solo un mensaje parcial siendo enviado. Básicamente, el servidor recibe una solicitud posterior, pero no hay un cuerpo.

Para la posteridad, aquí está el código que utilicé adjunto como la ventana. Antes de descargar la función de escucha:

var xhr = new XMLHttpRequest(); xhr.open("POST", <your url here>); xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); var payload = {id: "123456789"}; xhr.send(JSON.stringify(payload)); for(var i = 0; i < 100000000; i++) {}

Probé en:

Chrome 61.0.3163.100

IE 11.608.15063.0CO

Edge 40.15063.0.0