ASP.NET Core Razor Pages:浏览器/标签页关闭时记录用户登出时间
解决方案
1. 区分合法导航与关闭操作
先给站内所有导航元素(链接、表单按钮等)添加标记,让脚本能区分用户是正常跳转还是关闭页面:
// 标记是否为合法站内导航 let isLegitimateNavigation = false; // 监听站内链接点击 document.addEventListener('click', function(e) { const targetLink = e.target.closest('a'); if (targetLink && targetLink.host === window.location.host) { isLegitimateNavigation = true; } }); // 监听表单提交(比如主动登出的表单) document.addEventListener('submit', function() { isLegitimateNavigation = true; });
2. 优化页面卸载事件处理
只在用户关闭标签页/浏览器时弹出确认,并且用稳定的方式发送登出请求:
window.addEventListener('beforeunload', function(e) { // 合法导航时不弹出提示 if (isLegitimateNavigation) return; // 弹出确认对话框 const confirmText = '确定要离开吗?系统将记录您的登出时间'; e.returnValue = confirmText; return confirmText; }); window.addEventListener('unload', function() { // 仅非合法导航时发送登出请求 if (!isLegitimateNavigation) { // 使用sendBeacon保证请求稳定发送,不会被浏览器中断 navigator.sendBeacon('/Logout'); } });
如果你的后端只接受GET请求,也可以用图片请求替代:
window.addEventListener('unload', function() { if (!isLegitimateNavigation) { const img = new Image(); img.src = '/Logout'; } });
3. 后端登出逻辑实现
在Logout.cshtml.cs中处理登出和时间记录:
public async Task<IActionResult> OnGet() { // 获取当前用户ID var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (!string.IsNullOrEmpty(userId)) { // 替换为你的数据库操作,记录登出时间 await _userLogService.LogLogoutTime(userId, DateTime.UtcNow); } // 执行登出操作 await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return RedirectToPage("/Index"); }
核心要点
- 合法导航标记:避免页面内跳转、表单提交时弹出不必要的提示
- 稳定请求方式:
navigator.sendBeacon是浏览器专门为页面卸载场景设计的API,能保证请求被正常发送,不会像普通Ajax那样被浏览器中断 - 兼容性:上述方案支持所有现代浏览器,适配ASP.NET Core 8.0环境
内容的提问来源于stack exchange,提问作者Yuvraj Jadhav
相关产品推荐
相关产品推荐

