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

javascript browser

73145 просмотра

10 ответа

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

Автор: ashish bhatt Источник Размещён: 12.11.2019 09:06

Ответы (10)


45 плюса

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

Я хотел отключить пользователя на сервере, когда вкладка или окно браузера были закрыты, но не тогда, когда страница была перезагружена (вы можете различать события перезагрузки / закрытия для другой цели, но вы можете воспользоваться моим решением). Я закончил со следующим процессом, основанным на локальном хранилище 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 также ненадежна, потому что кнопки не размещаются в одной и той же позиции в каждом браузере (например, кнопка закрытия слева).

Автор: Julien Kronegg Размещён: 17.12.2012 03:18

6 плюса

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

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

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

Автор: Walter Rumsby Размещён: 05.10.2009 12:51

1 плюс

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

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

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

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

Автор: Alessandro Размещён: 12.05.2017 08:46

0 плюса

Используйте событие window.onbeforeunload для случая, чтобы перейти от страницы, но оно будет включать в себя теги обновления или привязки .... используйте флаг проверки для того же самого, 1 примером для процесса является проверка URL (Initial URL = current 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>
Автор: krunal nanda Размещён: 03.11.2014 12:57

0 плюса

Кредит 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');
})
Автор: KingMario Размещён: 29.08.2019 09:32

-1 плюса

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

Автор: Suresh Размещён: 15.04.2015 09:39

-1 плюса

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

Автор: Barry Bazini Размещён: 25.09.2016 02:36

-1 плюса

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

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();
  }
}
Автор: blazehub Размещён: 28.06.2018 10:35

-2 плюса

Мое предыдущее решение работало для меня в 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>
Автор: Real Red. Размещён: 20.02.2009 01:56

-8 плюса

<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>
Автор: Real Red. Размещён: 20.02.2009 10:40
Вопросы из категории :
32x32