如何检测并捕获非用户主动触发的window.open调用
window.open 调用监听实现方案
浏览器没有提供原生的addEventListener接口可以直接监听window.open的调用,但可以通过重写原生window.open方法的方式实现全量调用捕获,同时支持区分是否为用户主动触发的行为。
实现代码
// 先缓存原生的window.open方法 const nativeWindowOpen = window.open; // 重写window.open方法,注入监听逻辑 window.open = function (...args) { // 提取调用参数 const openUrl = args[0]; const openName = args[1]; const openFeatures = args[2]; // 自定义监听逻辑,可在此处做日志上报、行为拦截等操作 const isUserTriggered = event?.isTrusted ?? false; if (!isUserTriggered) { // 捕获到非用户主动触发的window.open行为,按需处理 console.log('捕获到自动触发的window.open调用', { url: openUrl, name: openName, features: openFeatures }); } // 不需要拦截的话,正常执行原生打开逻辑 return nativeWindowOpen.apply(this, args); // 如果需要拦截所有非用户触发的打开行为,替换上面的return逻辑即可: // if (isUserTriggered) { // return nativeWindowOpen.apply(this, args); // } // return null; }
注意事项
- 重写逻辑必须在所有会调用
window.open的业务代码执行之前完成,否则早于重写操作的调用不会被捕获。你给出的5秒延时调用场景,只要重写逻辑在setTimeout定义之前执行即可正常捕获。 - 逻辑中通过事件的
isTrusted属性区分触发来源:用户主动交互(点击、按键等)触发的事件该属性为true,脚本自动执行的调用该属性为false,完全符合你区分非用户主动操作的需求。 - 如果页面内有其他脚本也对
window.open做了重写,可能会出现逻辑冲突,需根据实际场景调整重写操作的执行优先级。
内容的提问来源于stack exchange,提问作者Lynn Rey
相关产品推荐
相关产品推荐

