使用OnBeforeUnload事件进行浏览器刷新

4
在网页上,当用户点击登出按钮时,我有一个 JavaScript 函数会清除存储在 MongoDB 上的用户会话。它运行正常。
此外,我希望在用户关闭浏览器时也清除用户会话。这里遇到了一个问题:当用户点击刷新图标时,登出函数会被调用。我只想在浏览器关闭时调用此函数。
我能否防止在页面刷新时调用此函数?
我的逻辑是在关闭浏览器时清除会话。我正在删除存储在 MongoDB 中的会话。是否有更好的管理会话的方法?
var isRefresh = false;
$(window).keydown(function (event) {
    if (event.keyCode == 116) { // User presses F5 to refresh
        refresh = true;
    }
});

// Calls the logout function when you close the browser thus cleans the session data.
var windowsCloseEventListener = window.attachEvent || window.addEventListener;
var chkForBrowserCloseEvents = window.attachEvent ? 'onbeforeunload' : 'beforeunload'; /// make IE7, IE8 compitable
windowsCloseEventListener(chkForBrowserCloseEvents, function (e) { // For >=IE7, Chrome, Firefox
    if (!isRefresh) {
        $scope.logout();
    }
});
6个回答

2

如Alex所建议,你可以使用会话Cookie来检查你的网站是否在当前会话中被访问(支持IE7以上)。

例子

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}

var isRefresh = true;
var sessionAlive = readCookie("sessionAlive");
if (sessionAlive === null) {
    isRefresh = false;
    sessionStorage.setItem("sessionAlive", true);
}

var windowsCloseEventListener = window.attachEvent || window.addEventListener;
var chkForBrowserCloseEvents = window.attachEvent ? 'onbeforeunload' : 'beforeunload';
windowsCloseEventListener(chkForBrowserCloseEvents, function (e) {
    if (!isRefresh) {
        $scope.logout();
    }
});

你可以使用更符合HTML5标准的sessionStorage来判断浏览器是否已关闭(新会话)(支持IE8+)。 例子:
var isRefresh = true;
var sessionAlive = sessionStorage.getItem("sessionAlive");
if (sessionAlive === null) {
    isRefresh = false;
    sessionStorage.setItem("sessionAlive", true);
}

var windowsCloseEventListener = window.attachEvent || window.addEventListener;
var chkForBrowserCloseEvents = window.attachEvent ? 'onbeforeunload' : 'beforeunload';
windowsCloseEventListener(chkForBrowserCloseEvents, function (e) {
    if (!isRefresh) {
        $scope.logout();
    }
});

readCookie源自:http://www.quirksmode.org/js/cookies.html


(说明:此处为原文内容,无需翻译)

2
据我所知,您实际上无法测试浏览器是否关闭;您只能测试窗口(或选项卡)是否关闭。这通常足够了,除非当然会发生页面刷新,因为它在窗口或选项卡内计数为关闭和重新打开网页。需要的是一个点击浏览器页面刷新按钮的事件处理程序,但我不确定是否存在这样的处理程序。这里有一些链接:

如何在提交更改时显示“您确定要离开此页吗?”

以及

处理浏览器关闭事件和页面刷新

在尝试查找有关页面刷新事件处理程序的信息时,我遇到的一件事是使用“本地存储”的概念。您可以在 on-before-unload 处理程序的一部分中将一个小的数据项(时间戳)放入本地存储中。在服务器上激活一种计时器,并等待该时间到期,然后再清除会话。当加载页面时,测试本地存储是否存在该数据项。如果存在并且时间戳非常近,则知道页面已刷新,并且可以根据此进行适当的操作--例如向服务器发送 AJAX 消息,告诉它暂时不要清除会话。

2
为更好地管理会话并避免用户按下浏览器刷新键,您需要:
  • 当窗口关闭时,删除注销功能。
  • 在客户端和服务器上实现不活动监视器,如果用户长时间未活动,则会清除会话。因此,如果用户关闭浏览器,MongoDB中的会话将持续一段时间,直到服务器清除它。
  • 从客户端向服务器实现keepalive ping,如果用户在页面上活动,则每隔一定时间间隔ping服务器。为了减少网络流量,您可以每当使用AJAX或RESTful API调用服务器时重新安排keepalive。
  • 在本地存储中保存用户会话以便在浏览器刷新时重新读取会话。
这个InActivity监视器可以是一个很好的起点:https://github.com/HackedByChinese/ng-idle/blob/develop/src/angular-idle.js。 我已在我的Angular项目中完成了以上所有内容。希望这有所帮助。

非常感谢,我会仔细研究您的解决方案。 - Jackal

1
使用带有会话过期时间的Cookie应该可以正常工作。

你需要创建一个没有设置过期日期的cookie。就这样。我不知道你使用哪些库,如果使用jquery.cookie,它会像这样:$.cookie('MY_SSID', 'value')。 http://en.wikipedia.org/wiki/HTTP_cookie#Session_cookie - Alex Ivasyuv

0

WindowEventHandlers.onbeforeunload

window.onbeforeunload = function(e) {
  return 'Dialog text here.';
};

此示例显示,addEventListener和attachEvent方法不能用于onbeforeunload事件(仅适用于Google Chrome和Safari):

 if (window.addEventListener) {  // all browsers except IE before version 9
            window.addEventListener ("beforeunload", OnBeforeUnLoad, false);
        }
        else {
            if (window.attachEvent) {   // IE before version 9
                window.attachEvent ("onbeforeunload", OnBeforeUnLoad);
            }
        }

            // the OnBeforeUnLoad method will only be called in Google Chrome and Safari
        function OnBeforeUnLoad () {
            return "All data that you have entered will be lost!";
        }

0

你可以使用"onbeforeunload"事件来处理这种情况。

$wnd.onbeforeunload = function(e) {

        var logoutClicked = callSomeFunctionToGetIfLogoutButtonIsClicked();
        if (!logoutClicked) {
            return "Some message";
        }
        return;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接