浏览器标签页切换密码保护功能异常排查求助
标签页切换密码验证功能修复方案
问题根源分析
你的代码出现时好时坏的问题,核心源于以下几个逻辑漏洞:
- 重复绑定
visibilitychange事件,导致同一操作触发多次验证逻辑 - 多标签页场景下,
sessionStorage的变更无法同步到其他标签页的内存变量authenticated,造成状态不一致 - 页面隐藏时机不合理,用户刚切换标签就清空认证状态并隐藏页面,易引发状态冲突
- 未处理用户点击密码输入框「取消」的情况,导致无限递归调用
修复后的完整代码
<script type="text/javascript"> // 设定验证密码 const password = "12"; // 初始化认证状态,优先从sessionStorage读取 let authenticated = sessionStorage.getItem("authenticated") === password; // 隐藏页面内容 function hidePage() { document.body.style.display = "none"; } // 显示页面内容 function showPage() { document.body.style.display = "block"; } // 密码验证弹窗 function promptPassword() { const input = prompt("Please enter the password:"); // 处理用户取消输入的情况 if (input === null) { hidePage(); setTimeout(promptPassword, 500); return; } if (input === password) { authenticated = true; sessionStorage.setItem("authenticated", password); showPage(); } else { setTimeout(promptPassword, 500); } } // 处理标签页可见性变化 function handleVisibilityChange() { // 仅当页面从隐藏恢复为可见时,检查认证状态 if (!document.hidden && !authenticated) { hidePage(); promptPassword(); } } // 监听storage事件,同步多标签页的认证状态 window.addEventListener("storage", (e) => { if (e.key === "authenticated") { authenticated = e.newValue === password; if (authenticated) { showPage(); } else { hidePage(); promptPassword(); } } }); // 初始化逻辑 if (!authenticated) { hidePage(); promptPassword(); } // 仅绑定一次visibilitychange事件 document.addEventListener("visibilitychange", handleVisibilityChange); </script>
关键修改说明
- 避免重复绑定事件:仅在初始化时绑定一次
visibilitychange事件,移除原代码中在验证逻辑内重复绑定的操作,防止多次触发。 - 多标签页状态同步:新增
storage事件监听,当其他标签页修改sessionStorage中的认证状态时,自动同步当前标签页的authenticated变量,保证多标签页状态一致。 - 优化页面隐藏时机:仅在页面从隐藏状态恢复且未认证时,才隐藏页面并触发验证,不再在用户离开标签页时立即清空状态,减少不必要的状态变更。
- 处理取消输入场景:判断用户点击「取消」按钮的情况(
input === null),避免无限递归调用,同时保持页面隐藏状态。 - 统一状态初始化:直接从
sessionStorage初始化authenticated变量,简化逻辑,保证内存状态与存储状态一致。
内容的提问来源于stack exchange,提问作者nick
相关产品推荐
相关产品推荐

