用户直接关闭浏览器如何自动退出

本文介绍了一种通过监听window.onload和window.onbeforeunload事件来区分用户刷新和关闭浏览器的方法,通过发送不同的参数到后端,实现自动注销或取消退出操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般搜索结果都是一个监听事件, 即 onunload onbeforeunload 事件, 但有一个致命性的缺陷, 那就是当用户刷新的时候这些事件同样也会触发. 这时候如何区分成为了难题.

这里给出一个区分的思路:

首先在浏览器内监听两个事件, 一个是载入事件 load,   另一个是销毁前的事件 onbeforeunload, 用户刷新后, 一定是先触发销毁事件然后是载入事件. 就是利用了这个顺序完成的监听过程.

触发销毁事件, 事件内部发送给后台一个请求,携带参数 eventName=load , 后台接收后先不要直接退出, 而是生成一个十秒左右的定时器, 定时器在十秒后自动注销当前账户. 用户刷新并触发载入事件时, 事件内部同样发送后台一个请求,携带参数 eventName=unload 后台接收后取消定时器.

如果是关闭浏览器, 则只触发上一步, 十秒后依然会自动退出. 这样就达到区分的目的了.

示例代码:

// 前端载入页面事件
window.onload = function () {
  let httpRequest = new XMLHttpRequest()   // 第一步:建立所需的对象
  httpRequest.open('POST', '/user/logout') // 第二步:打开连接
  httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
  httpRequest.send('eventName=load')         // 第三步:携带参数
  httpRequest.onreadystatechange = function () {}
}
// 前端销毁页面事件
window.onbeforeunload = function () {
  let httpRequest = new XMLHttpRequest()   // 第一步:建立所需的对象
  httpRequest.open('POST', '/user/logout') // 第二步:打开连接
  httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
  httpRequest.send('eventName=unload')   // 第三步:携带参数
  httpRequest.onreadystatechange = function () {}
}
// 后端 java 处理事件
// 使用 SaToken 进行演示
@PostMapping("/user/logout")
public void logout(String eventName) {
	if (!StpUtil.isLogin()) {
	    System.out.println("未登录状态下什么都不做");
		return;
	}
	System.out.println("执行退出: " + eventName);
	if (eventName == null) {
        System.out.println("用户正常点击按钮退出");
		StpUtil.logout();
	} else {
		SaSession session = StpUtil.getSession();
		String timerKey = "userCloseEventTimer";
		if ("unload".equals(eventName)) {
			System.out.println("10秒后退出");
			Integer loginId = StpUtil.getLoginIdAsInt();
			// 开启定时
			TimerTask timerTask = new TimerTask() {
				@Override
				public void run() {
					System.out.println("自动退出");
					StpUtil.logout(loginId);
				}
			};
			Timer timer = new Timer();
			timer.schedule(timerTask, 10_000); // 控制时长
			session.set(timerKey, timer);
		} else if ("load".equals(eventName)){
			// 关闭定时
			if (session.has(timerKey)) {
				System.out.println("取消退出");
				Timer timer = session.getModel(timerKey, Timer.class);
				timer.cancel();
				session.delete(timerKey);
			}
		}
	}
}

十秒只是一个范围, 可以动态修改.

参考文献: load事件  beforeunload事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值