如何防止页面检测到用户离开页面或点击窗口外部的行为?
拦截网页离页/失焦检测的实现方案
结论先行:不需要强制使用Greasemonkey,这类基于JS的离页检测有多种拦截路径,Greasemonkey这类用户脚本管理器只是适配成本最低的方案之一,不是唯一选项。
网页常见的离页/失焦检测逻辑
站点用来识别用户离开当前页面的JS逻辑基本围绕以下几类API和事件实现:
- 监听
visibilitychange事件,读取document.hidden、document.visibilityState属性判断标签页是否被切到后台 - 监听窗口/文档层的
blur、focusout事件,判断当前窗口是否失去焦点 - 监听
mouseleave、mouseout事件,判断鼠标是否移出页面可视区域 - 定时轮询
document.hasFocus()方法的返回值,校验页面是否处于激活状态 - 部分站点会额外检测窗口失焦后的计时器精度变化,判断用户是否切走了窗口
具体拦截方案
方案1:用户脚本拦截(最常用,不局限于Greasemonkey)
Greasemonkey、Tampermonkey、Violentmonkey这类用户脚本管理器都可以实现,核心是在页面业务脚本加载前,劫持相关API、拦截对应事件,向页面返回伪造的「用户始终在页面内」的状态。
脚本需要配置@run-at document-start确保优先执行,核心代码参考:
// 伪造页面可见性属性 Object.defineProperty(document, 'hidden', { get: () => false, configurable: true }); Object.defineProperty(document, 'visibilityState', { get: () => 'visible', configurable: true }); // 劫持焦点检测方法 Document.prototype.hasFocus = () => true; // 拦截所有会触发离页判定的事件,阻止页面业务监听器收到事件 const blockEventList = ['visibilitychange', 'blur', 'focusout', 'mouseleave', 'mouseout']; blockEventList.forEach(eventName => { window.addEventListener(eventName, e => { e.stopImmediatePropagation(); e.preventDefault(); }, true); document.addEventListener(eventName, e => { e.stopImmediatePropagation(); e.preventDefault(); }, true); });
如果站点做了反调试、事件签名校验,需要针对性调整劫持逻辑,通用脚本可能无法覆盖所有场景。
方案2:开发者工具临时拦截
如果只是单次临时使用,不需要安装脚本管理器:打开目标页面后按F12调出开发者工具,在控制台执行上述劫持代码,同时可以在Sources面板的事件监听断点中,勾选对应失焦、可见性变化事件,断点阻断站点检测逻辑的执行即可。该方案的缺点是页面刷新后需要重新操作。
方案3:专用浏览器扩展/启动参数
Chromium、Firefox都有专门用来伪造标签页活跃状态的扩展,部分定制版浏览器也自带标签页后台保活、状态伪造功能,不需要手动写代码,但灵活度较低,遇到定制化的检测逻辑容易失效。
注意事项
- 不要使用该类方法绕过在线考试、实名认证、付费内容观看场景的检测规则,违反站点服务协议可能导致账号被限制、封禁
- 部分站点会检测用户脚本注入痕迹,使用时需要额外处理脚本的注入特征
内容的提问来源于stack exchange,提问作者plshelpmeout
相关产品推荐
相关产品推荐

