Определение между обновлением и закрытием действий браузера

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

Ответ 1

Существует решение.

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

Ответ 4

Используйте событие 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>

Ответ 5

Кредит https://www.anandkanatt.com/how-do-i-detect-browser-window-closed-refreshed/#comment-15892. Я немного упростил это, используя сам нож для проверки. Протестировано в Chrome версии 78.0.3887.7.

Вы можете попробовать это:

  • Добавьте файл refresh-close-detector.html. Вот пример кода:
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Processing...</title>
</head>
<body>

<script>
  if (this.opener) {
    // the opener was refreshed, do something if you want
  } else {
    // the opener was closed, do something if you want
  }

  // you may want to close the pop up
  this.close()
</script>
</body>
</html>
  • На странице, которую вы хотите определить между обновлением и закрытием действий браузера, добавьте прослушиватель событий для выгрузки:
window.addEventListener('unload', () => {
  open('refresh-close-detector.html', '', 'width=100,height=100');
})

Ответ 6

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

Ответ 7

    $(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 (window) для определения, закрыты или просто перезагружены. работаю для меня.

Ответ 8

Это рабочее решение

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();
  }
}

Ответ 9

Мое предыдущее решение работало для меня в IE. window.event будет undefined для браузеров, отличных от 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>

Ответ 10

<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>