Определение между обновлением и закрытием действий браузера - PullRequest
36 голосов
/ 20 февраля 2009

Когда мы обновляем страницу (F5 или значок в браузере), она сначала вызвать событие ONUNLOAD. Когда мы закрываем браузер (X на правом верхнем значке), он будет вызвать событие ONUNLOAD. Теперь, когда инициируется событие ONUNLOAD, нет возможности различить обновление страницы или закрытие браузера. Если у вас есть решение, дайте мне.

Ответы [ 9 ]

43 голосов
/ 17 декабря 2012

Есть решение.

Я хотел отключить пользователя на сервере, когда вкладка или окно браузера были закрыты, но не тогда, когда страница была перезагружена (вы можете различать события перезагрузки / закрытия для другой цели, но вы можете воспользоваться моим решением) , Я закончил со следующим процессом, основанным на локальном хранилище HTML5 и клиент-серверной связи AJAX:

  1. на вашей странице, добавьте onunload к window для следующего обработчика (псевдо-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. на своей странице, добавьте onload на body к следующему обработчику (псевдо-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. на сервере, собрать запросы на отключение в список и установить поток таймера, который проверяет список через регулярные промежутки времени (я использовал каждые 20 секунд). По истечении времени ожидания запроса на отключение (т. Е. 5 секунд прошло) отключите пользователя от сервера. Если за это время получен запрос на отключение, соответствующий запрос на удаление будет удален из списка, чтобы пользователь не был отключен.

Этот подход также применим, если вы хотите провести различие между событием закрытия вкладки / окна и переходом по ссылкам или отправленной форме. Вам просто нужно разместить два обработчика событий на каждой странице, которая содержит ссылки и формы, и на каждой целевой странице ссылки / формы.

Обратите внимание, что я использую событие unload вместо события beforeUnload для правильного управления ссылками на вложения: когда пользователь нажимает ссылку на вложение (например, файл PDF), событие beforeUnload отправляется, затем появляется всплывающее окно открытия / сохранения и ничего более (браузер не изменяет отображаемую страницу и не отправляет событие unload). Если бы я использовал событие beforeUnload (как я делал раньше), я бы обнаружил изменение страницы, когда его нет.

Этот подход ограничен браузерами, которые поддерживают локальное хранилище HTML5, поэтому вы, вероятно, использовали бы специальные подходы для старых браузеров, таких как MSIE7.

Другие подходы, основанные на event.clientY, ненадежны, поскольку это значение является отрицательным при нажатии на кнопки перезагрузки или закрытия вкладки / окна, и положительным, когда для перезагрузки используются сочетания клавиш (например, F5, Ctrl-R, .. .) и закрытие окна (например, Alt-F4). Полагаться на положение события X также ненадежно, поскольку кнопки не размещаются в одной и той же позиции в каждом браузере (например, кнопка закрытия слева).

6 голосов
/ 05 октября 2009

К сожалению, проверка значения события clientY / pageY, как предлагается в некоторых ответах здесь, не является надежным способом определить, запускается ли событие unload вследствие действия пользователя. закрытие страницы

Причина, по которой clientY / pageY является отрицательной при нажатии кнопки закрытия браузера, заключается в том, что кнопка закрытия расположена над верхней частью документа (т.е. над пикселем 0), но кнопка перезагрузки означает, что нажатие кнопка перезагрузки также приведет к отрицательному значению для clientY / pageY.

Переход по пути проверки x-координаты события также проблематичен, поскольку кнопка закрытия браузера не всегда находится с правой стороны окна (например, слева в OS X) и потому что окно можно закрыть, закрыв вкладку или с помощью клавиатуры.

1 голос
/ 12 мая 2017

Сегодня у меня возникла та же проблема, и я нашел возможное решение, которым хочу поделиться с вами.

Размышляя о том, что может помочь различить обновление и закрытие, мне в голову пришли файлы cookie. Я помню, что установка cookie без явного срока действия делает его доступным только для текущего сеанса. И текущий сеанс явно действителен, пока браузер не будет закрыт. Это не включает закрытие вкладки, но моя проблема была связана с аутентификацией пользователя, и я не хотел выходить из системы только для пользователя, закрывшего вкладку (я думаю, что это тот же подход, что и ASPXAUTH cookie ASP.NET).

Итак, я помещаю простой файл cookie в коллекцию document.cookies, когда пользователь вошел в систему и проверил его при загрузке страницы: если файл cookie все еще был там, это была обновленная или вновь открытая вкладка, и пользовательские данные сохранялись, если файл cookie не был текущий сеанс истек, поэтому пользовательские данные были очищены (так же, как явный выход из системы).

Надеюсь, что этот подход может быть полезен кому-то еще!

0 голосов
/ 28 июня 2018

Это рабочий раствор

export class BootstrapComponent implements OnInit {

  validNavigation = 0;

  constructor(
    private auth: AuthenticationService
  ) { }

  ngOnInit() {
    const self = this;
    self.registerDOMEvents();
  }

  registerDOMEvents() {
    const self = this;
    window.addEventListener('unload', () => {
      if (self.validNavigation === 0) {
        self.endSession();
      }
    });
    document.addEventListener('keydown', (e) => {
      const key = e.which || e.keyCode;
      if (key === 116) {
        self.validNavigation = 1;
      }
    });
  }

  endSession() {
    const self = this;
    self.auth.clearStorage();
  }
}
0 голосов
/ 25 сентября 2016
    $(window).bind('unload', function () {
        if (/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) {
            console.log('firefox delete');
            var data = { async: false };
            endSession(data);
            return null;
        }
        else {
            console.log('NON-firefox delete');
            var data = { async: true };
            endSession(data);
            return null;
        }
    });

    function endSession(data) {
        var id = 0

        if (window) { // closeed
            id=1
        }

        $.ajax({
            url: '/api/commonAPI/'+id+'?Action=ForceEndSession',
            type: "get",
            data: {},
            async: data.async,
            success: function () {
                console.log('Forced End Session');
            }
        });
    }

Используйте if (окно), чтобы определить, закрыто или просто перезагрузить. работает на меня.

0 голосов
/ 16 апреля 2015

Я только что попробовал это, и это решило проблему: Создайте объект sessionStorage, который будет уничтожен, когда пользователь закроет браузер. Мы можем проверить объект sessionStorage, чтобы определить, закрыл ли пользователь браузер или обновил страницу (объект sessionStorage не будет уничтожен при обновлении страницы).

0 голосов
/ 03 ноября 2014

Используйте событие window.onbeforeunload для случая, чтобы отойти от страницы, но оно будет включать в себя теги обновления или привязки .... используйте для этого флаг проверки, 1 примером для процесса является проверка URL (Первоначальный URL) = текущий URL) или проверка F5 с использованием ключевого кода для обновления, в случае тегов привязки используйте bind ()

Примечание * Код ключа может вызвать проблемы в случае Chrome.

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>

<style type='text/css'>
body {
    font-family: sans-serif;
}
</style>
<script src="jquery-1.9.1.js" type='text/javascript'></script>
<script type='text/javascript'>
var valid=false;
function wireUpEvents() {

if(valid){
alert("Page Refreshed or Redirected");
}else{

window.onbeforeunload = askWhetherToClose;

}
function askWhetherToClose(event) {

if(!valid){

    var msg;

    msg = "You're leaving the page, do you really want to?";
    event = event || window.event;
    event.returnValue = msg;
    return msg;
}}
$(document).bind('keypress', function(e) { 
 if (e.keyCode == 116){ 

 // or you can insert some code to check page refresh
 valid = true; 

//wireUpEvents();
 } 
 }); 
 $("a").bind("click", function() {
//To check redirection using Anchor tags  
 valid = true; 
 //wireUpEvents();
 }); 
 }
$(document).ready(function() { 
 wireUpEvents(); 

 });
</script>
</head>
<body>
<p>Close the browser window, or navigate to <a href="http://stackoverflow.com">StackOverflow</a></p>
</body>
</html>
0 голосов
/ 20 февраля 2009

Мое предыдущее решение работало для меня в IE. window.event не будет определяться для браузеров, отличных от IE, поскольку 'событие' определяется глобально в IE, в отличие от других браузеров Вам нужно будет указать событие в качестве параметра в случае других браузеров. Также, что clientX не определен для Firefox, мы должны использовать pageX.

Попробуйте что-то вроде этого .... должно работать для IE и Firefox это ...

<html>
<body>
<script type="text/javascript">

window.onunload = function(e) {
// Firefox || IE
e = e || window.event;

var y = e.pageY || e.clientY;

if(y < 0)  alert("Window closed");
else alert("Window refreshed");

}
</script>
</body>
</html>
0 голосов
/ 20 февраля 2009
<html>
<body onunload="doUnload()">
<script>
   function doUnload(){
     if (window.event.clientX < 0 && window.event.clientY < 0){
       alert("Window closed");
     }
     else{
       alert("Window refreshed");
     }
   }
</script>
</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...