You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不限制截图时模糊密码字段?能否捕获截图前事件?

如何在截图时模糊密码字段(不限制用户截图操作)

这个问题问得很好——既要满足安全需求模糊密码,又不想限制用户的截图操作,确实需要一些巧妙的前端技巧。下面我会分享几个可行的技术方案,从原生API到降级策略都有覆盖:

方案一:利用浏览器原生的「捕获状态」检测(最可靠)

Chrome 89+、Edge 89+ 支持一个非常实用的特性:当页面被屏幕捕获(包括截图、录屏)时,document.visibilityState会切换为captured状态。我们可以监听这个状态变化,动态隐藏真实密码、替换为星号或模糊效果,捕获结束后再恢复。

代码示例

<input type="password" id="passwordInput" placeholder="输入密码" />
const passwordInput = document.getElementById('passwordInput');
let realPassword = '';

// 实时保存真实密码的副本
passwordInput.addEventListener('input', (e) => {
  realPassword = e.target.value;
});

// 监听页面可见性变化
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'captured') {
    // 截图时,替换为等长星号并切换为文本输入框(避免原生密码框的圆点样式被截图保留)
    passwordInput.type = 'text';
    passwordInput.value = '*'.repeat(realPassword.length);
  } else {
    // 恢复原生密码输入框和真实密码
    passwordInput.type = 'password';
    passwordInput.value = realPassword;
  }
});

优缺点

  • ✅ 最准确:直接响应浏览器的捕获事件,覆盖所有截图/录屏场景(包括系统快捷键、第三方工具)
  • ❌ 兼容性有限:目前仅Chrome、Edge支持,Firefox和Safari暂未实现此状态

方案二:系统截图快捷键检测(降级补充)

对于不支持captured状态的浏览器,我们可以监听系统默认的截图快捷键,在用户按下时临时模糊密码。虽然无法覆盖所有截图场景(比如右键截图、第三方工具自定义快捷键),但能覆盖大部分用户的常规操作。

代码示例

const passwordInput = document.getElementById('passwordInput');
let realPassword = '';
let isMetaKeyPressed = false; // 记录Win/Cmd键是否按下

// 保存真实密码
passwordInput.addEventListener('input', (e) => {
  realPassword = e.target.value;
});

// 监听键盘按下事件
window.addEventListener('keydown', (e) => {
  if (e.key === 'Meta') {
    isMetaKeyPressed = true;
  }

  // Windows截图:Win + PrtScn
  if (isMetaKeyPressed && e.key === 'PrintScreen') {
    blurPassword();
  }
  // Mac截图:Cmd + Shift + 3/4
  if (isMetaKeyPressed && e.shiftKey && (e.key === '3' || e.key === '4')) {
    blurPassword();
  }
});

// 监听键盘松开事件,恢复密码
window.addEventListener('keyup', (e) => {
  if (e.key === 'Meta') {
    isMetaKeyPressed = false;
    restorePassword();
  }
});

// 模糊密码的辅助函数
function blurPassword() {
  passwordInput.type = 'text';
  passwordInput.value = '*'.repeat(realPassword.length);
}

// 恢复密码的辅助函数
function restorePassword() {
  passwordInput.type = 'password';
  passwordInput.value = realPassword;
}

优缺点

  • ✅ 兼容性好:支持所有现代浏览器
  • ❌ 覆盖范围有限:无法处理非快捷键触发的截图操作

方案三:自定义密码输入组件(增强安全兜底)

如果想要进一步降低密码暴露的风险,可以实现一个自定义密码输入组件:用两个输入框叠加,一个显示星号(默认可见),一个是真实密码输入框(仅在用户聚焦时可见)。结合前面的两种方案,可以最大化减少真实密码出现在截图中的概率。

代码示例

<div class="custom-password-wrapper">
  <input type="text" id="fakePassword" readonly placeholder="输入密码" />
  <input type="password" id="realPassword" class="hidden-input" placeholder="输入密码" />
</div>
.custom-password-wrapper {
  position: relative;
  width: 200px;
}

.hidden-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: text;
}
const fakePassword = document.getElementById('fakePassword');
const realPassword = document.getElementById('realPassword');

// 同步真实密码到星号显示框
realPassword.addEventListener('input', (e) => {
  fakePassword.value = '*'.repeat(e.target.value.length);
});

// 聚焦时切换到真实密码输入框
realPassword.addEventListener('focus', () => {
  fakePassword.style.display = 'none';
  realPassword.classList.remove('hidden-input');
});

// 失焦时切回星号显示框
realPassword.addEventListener('blur', () => {
  realPassword.classList.add('hidden-input');
  fakePassword.style.display = 'block';
});

// 结合方案一的捕获状态检测,强制显示星号框
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'captured') {
    realPassword.classList.add('hidden-input');
    fakePassword.style.display = 'block';
  }
});

优缺点

  • ✅ 安全兜底:平时用户看不到真实密码,只有主动聚焦时才显示
  • ✅ 兼容性好:所有浏览器都支持
  • ❌ 实现稍复杂:需要处理输入同步、焦点切换等细节

总结建议

  1. 优先采用方案一作为核心逻辑,因为它是最可靠的原生检测方式;
  2. 搭配方案二作为降级策略,覆盖不支持captured状态的浏览器;
  3. 可选方案三进一步增强安全性,减少真实密码暴露的场景。

另外需要注意:不要在前端存储敏感密码的明文副本到 localStorage 或其他持久化存储中,仅在内存中临时保存即可,避免额外的安全风险。

内容的提问来源于stack exchange,提问作者Akhil Bodhade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 13:37:45