Достаточно просто создать приложение Ajax, которое проверяет все ответы, чтобы убедиться, что они не указывают на истечение сеанса, и если сеанс истек, автоматически выйдите из системы с дружественным «Ваш сеанс истек из-за неактивности "сообщение об ошибке.
Но в приложениях Ajax часто встречаются следующие случаи:
- Пользователь вошел в систему, успешно используя приложение, получая данные через http с установленным сеансом http
- Пользователь закрывает ноутбук
- Тайм-аут хоста http через N минут
- Пользователь снова открывает ноутбук. Приложение Ajax выглядит живым и здоровым. Они нажимают вокруг, и это прекрасно, так как приложение позволяет им видеть вещи, которые они уже загрузили.
- Затем они нажимают на то, что требует загрузки данных, и данные возвращаются с указанием истечения сеанса
- Приложение Ajax выгоняет их и говорит: «Время сеанса истекло из-за неактивности».
Это действительно странно для пользователя, потому что они не были неактивными с их точки зрения.
Теперь, одна возможность состоит в том, чтобы иметь код Javascript на клиенте, который использует setTimeout () для периодического (скажем, каждые 15 минут, если время ожидания сеанса составляет 30 минут), чтобы инициировать запрос к хосту, чтобы спросить, сколько времени осталось в сессия. Эта периодическая проверка хороша тем, что позволяет показывать им предупреждение, когда они близки к истечении времени ожидания, например «Время вашей сессии истечет через 1 минуту, если вы ничего не сделаете».
Но это не помогает, когда машина пользователя приостановлена. Это связано с тем, что, согласно всем моим испытаниям во многих различных браузерах, время setTimeout применяется к истекшему времени выполнения, а не к истекшему реальному времени. То есть, если вы вызываете setTimeout ("alert ('hi')", 2 * 60 * 1000); а затем приостановите работу вашего компьютера через 10 секунд, подождите 5 минут и снова включите его, вам придется подождать еще 110 секунд, пока вы не получите это предупреждение (я не смог найти исчерпывающую документацию по этому поведению, но это очевидный факт ). Таким образом, это означает, что проверка периода может не произойти совсем после возобновления работы компьютера пользователя.
Мое решение для этого состоит в том, чтобы вместо того, чтобы проводить периодическую проверку на основе длинного setTimeout, вместо этого делать короткий setTimeout (скажем, каждые 5 секунд) и проверять время, прошедшее с момента последней проверки, с использованием new Date () .getTime (), чтобы получить фактическое время на часах. Таким образом, я всегда сверяюсь с реальными часами, и вместо того, чтобы клиент ждал от нуля до пятнадцати минут, прежде чем понял, что время ожидания истекло после приостановки, самое большее - около пяти секунд (плюс время отклика http), чтобы выяснить это.
Но мне не нравится это решение, потому что оно основано на частом прерывании по таймеру. Есть ли более разумный способ справиться с этим?