Как отследить что пользователь покинул страницу?

Появилась довольно интересная задачка красиво и вменяемого решения которой я не нашел.

Необходимо разлогинивать пользователя когда тот каким-либо образом покидает страницу (закрытие вкладки/браузера, переход на вкладке на другой портал и т.д.)



Решение по событиям unload и onbeforeunload не подходит по двум причинам:

1. Не работает в Опере

2. Требуется установка меток на каждый элемент допустимого перехода. Что само по себе кривовато выглядит. Плюс в проекте очень много аяксовых подгрузок элементов управления(ссылок, кнопок и т.п.), и все их нелегко отследить.



Session storage в браузере неплохое решение, но к сожалению он не очищается при переходе внутри вкладке на другую страницу в строке ввода адреса.



Делать постоянные аякс запросы на сервер с меткой «Я еще тут», плохой вариант, так как время реакции на закрытие вкладки нужно практически мгновенное, а при установке шага запроса, к примеру, в 5 секунд, мы будем выкидывать пользователя если у негшо страничка будет прогружаться дольше.



Может у кого-то есть идеи как это можно реализовать?



Браузеры все последние. IE 8+



UPD. Возможно некорректно выразился. Но мне нужно логаутить, не в тот момент когда пользователь переключился на другую задачу (свернул окно, переключился на другую вкладку), а в тот момент когда пользователь закрыл вкладку или в этой вкладке ушел по другом адресу
  • Вопрос задан
  • 25273 просмотра
Пригласить эксперта
Ответы на вопрос 9
Tehnomag
@Tehnomag
iframe, который постоянное держит подключение с сервером по websocket.
Сайт обнавляется в ifreme который не трогает подключение, как закрется окно — сессию можно удалять.

Из плюсов вижу возможность передавать всю информацию о клиенте: куда нажал, сколько грузится страница.

С IE 6 можно подружить

habrahabr.ru/post/94921/
Ответ написан
@artishok
кратко
window.onblur = function () {document.title='документ неактивен'}
Ответ написан
UZER2006
@UZER2006
Да никак вы этого не сделаете. Только «пингуя» сервак и соответственно реагируя при отсутствии активности. Конечная реализация – любая, на ваше усмотрение. Очевидно, что в таком случае пропавшее соединение так же будет считаться закрытием. Иначе никак.
Как вариант, можно попытаться при закрытии вкладки (window.beforeClose) отправить запрос, но если не задержать закрытие, он, скорее всего, не дойдёт. А задерживание закрытие и/или вообще какие-то уведомления будут очень раздражать посетителей.
Ответ написан
MonkAlbino
@MonkAlbino
Фронтенд разработчик
function logout() {
    // удаляем куку и перезагружаем страницу
}
var is_focus = 1;
window.onfocus = function()
{
    is_focus = 1;
}

window.onblur = function()
{
    is_focus = 0;
}

setInterval(function(){
   if(is_focus != 1) logout();
}, 1000);
Ответ написан
return
@return
Отказывайтесь от переходов по страницам и переходите на навигацию с помощью historyAPI (и хеши для старых браузеров), тогда сможете хранить идентификационные данные пользователя просто в пределах своей страницы :)
Ответ написан
Комментировать
@Louter
Программист
Для начала конечное тз (внести правки):
После открытия сайта site.com в N вкладках отслеживать, когда N = 0, т.е. нет вкладок с сайтом site.com. При наступлении события N = 0 производить логаут.

Пингуйте localStorage:
суть скерстить ежа с ужом, альфабанк и идея со сторейджем мне подсказали кое-что.
ping = getLS('ping'); // Когда открывается site.com мы смотрим из LS некую виличину (lastPingTime или для простоты просто ping). Получаем число)
currentTime = (new Date()).getTime(); //Получаем текущую метку времени
delta = 100; // количество миллисекунд для тревоги
interval = 42; // я ставлю 1/24-ую секунды, а так рекомендуемый интервал 20--50. Нет, не нагрузит. Да, интервал.
if (currentTime - delta > ping) { // если было перед этим закрытие или в первый раз
// я бы сбросил куки, прочую гадость, тут тело для логина
} else {
// если всё замечательно и юзер не закрывал нашу вкладку
}
setLS('ping', currentTime); // обновляем значение ping и
setInterval(function () { // добавляем таймер
  setLS('ping', currentTime); 
}, interval);


Суть, думаю, ясна. Я всё свёл к чему, что js и так всем правит. Если нужна безопасность, (а то вдруг юзер закроет вкладку, выключит js и снова откроет), то можете там же юзать и ключи безопасности, наподобии альфы или вообще всю страницу строить на основе ajax-ответов.
Так же вы можете юзать куку установив время жизни = 1с, и обновляя его, но на сколько это нагруженно я не знаю. Дерзайте!)
Ответ написан
Комментировать
@kidar2
Я бы попробовал сделать так:
На beforonunlod отправил бы синхронный запрос на сервер, что пользователь каким-либо образом начал выгружать (это может быть обновление по F5, или закрытие вкладки) страницу.
Затем на сервере ставим timeout о том, что пользователь выгрузил. Если через N времени, от пользователя не пришёл запрос на какую-либо страницу приложения, то вызываем для него logout.
Ответ написан
Комментировать
Может быть при помощи Visibility API или вот этой кросс-браузерной билиотекой: Visibility.js
Ответ написан
Комментировать
@dooreelkow
Сделать сервер, который на запрос «GET /presence?id=» уходит в спячку (принимает соединение, но не даёт ответа). Когда страница закрывается, броузер должен закрыть висящий сокет со своей стороны, что вызовет исключение на сервере. Это будет сигналом, что клиентская страница закрыта.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы