Есть решение.
Я хотел отключить пользователя на сервере, когда вкладка или окно браузера были закрыты, но не тогда, когда страница была перезагружена (вы можете различать события перезагрузки / закрытия для другой цели, но вы можете воспользоваться моим решением) , Я закончил со следующим процессом, основанным на локальном хранилище 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'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)
}
}
}
на сервере, собрать запросы на отключение в список и установить поток таймера, который проверяет список через регулярные промежутки времени (я использовал каждые 20 секунд). По истечении времени ожидания запроса на отключение (т. Е. 5 секунд прошло) отключите пользователя от сервера. Если за это время получен запрос на отключение, соответствующий запрос на удаление будет удален из списка, чтобы пользователь не был отключен.
Этот подход также применим, если вы хотите провести различие между событием закрытия вкладки / окна и переходом по ссылкам или отправленной форме. Вам просто нужно разместить два обработчика событий на каждой странице, которая содержит ссылки и формы, и на каждой целевой странице ссылки / формы.
Обратите внимание, что я использую событие unload
вместо события beforeUnload
для правильного управления ссылками на вложения: когда пользователь нажимает ссылку на вложение (например, файл PDF), событие beforeUnload
отправляется, затем появляется всплывающее окно открытия / сохранения и ничего более (браузер не изменяет отображаемую страницу и не отправляет событие unload
). Если бы я использовал событие beforeUnload
(как я делал раньше), я бы обнаружил изменение страницы, когда его нет.
Этот подход ограничен браузерами, которые поддерживают локальное хранилище HTML5, поэтому вы, вероятно, использовали бы специальные подходы для старых браузеров, таких как MSIE7.
Другие подходы, основанные на event.clientY
, ненадежны, поскольку это значение является отрицательным при нажатии на кнопки перезагрузки или закрытия вкладки / окна, и положительным, когда для перезагрузки используются сочетания клавиш (например, F5, Ctrl-R, .. .) и закрытие окна (например, Alt-F4). Полагаться на положение события X также ненадежно, поскольку кнопки не размещаются в одной и той же позиции в каждом браузере (например, кнопка закрытия слева).