邮箱脱敏必须用语义化正则(如^(.)(.*?)(@.*)$)动态替换,禁用截取、css隐藏或服务端只传脱敏串;需适配国际化、ssr、多字段差异及导出场景,并阻断反推路径。

前端做邮箱脱敏,不能靠 CSS 隐藏、data- 属性存原始值,或服务端只传“已脱敏字符串”就完事——得看谁控制精度、谁承担风险、谁决定 fallback 行为。
邮箱脱敏必须用正则替换,不是简单截取
常见错误是手动 email.substring(0, 1) + '****' + email.split('@')[1],但会崩在 u@x.com 或 test+tag@gmail.com 这类合法邮箱上。真正可靠的是带语义边界的正则:
-
^(.)(.*?)(@.*)$:捕获首字符、中间任意非贪婪段、@及之后全部 - 必须检查
middle.length === 0,否则a@b.c会被错变成a****@b.c - 用
'*'.repeat(middle.length)而不是固定'****',保证长度一致、避免样式错位
Vue/React 里别用过滤器或纯函数硬编码脱敏逻辑
组件内直接写 email.replace(/^(.)(.*?)(@.*)$/, ...) 看似省事,但问题集中爆发在三处:
- 不同字段(登录名、联系人邮箱、备用邮箱)脱敏规则可能不一致,比如备用邮箱要保留前 3 位:
^(.{3}).*(.@.*)$ - 国际化场景下,
@可能不在 ASCII 区间(极少见但存在),.*?会跨 Unicode 字符匹配出错 - SSR 渲染时若未同步执行脱敏,首屏可能闪现明文——必须在数据进入
data或useState前完成
后端没脱敏,前端补救也得守住底线
如果接口返回的是完整邮箱(比如历史遗留系统无法改后端),前端至少做到:
- 脱敏必须发生在 DOM 插入前,而不是靠
querySelectorAll('.email').forEach(...)后置处理——用户会看到 100ms 明文 - 所有邮箱字段都加
data-sensitized="email"属性,配合 CSPscript-src 'unsafe-inline'禁用,防止恶意脚本绕过脱敏逻辑 - 导出 Excel/PDF 时,不能复用前端 DOM 文本——得走单独的
/api/export?fields=email_masked接口,否则导出内容仍是明文
最常被忽略的一点:邮箱脱敏不是为了“看起来模糊”,而是阻断从展示层反推原始值的路径。只要正则没覆盖 +tag、sub.domain@ 或单字母本地部分,就等于留了后门。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











