前端表单校验与密码体验:原生约束、可访问提示和服务端验证
本文目录
前端校验的职责是帮助用户更早发现输入问题,不是证明请求可信。脚本可以被关闭,HTTP 请求可以绕过页面直接构造,因此所有安全与业务规则都必须在服务端再次检查。
先用语义化输入控件
邮箱可用 type="email",数字或日期字段按真实语义选择合适控件,并用 required、min、max 等原生约束表达简单规则。浏览器的邮箱检查只验证基本语法,不证明邮箱存在、用户拥有该邮箱或它符合你组织的业务规则。完整的格式规则往往比一个“万能邮箱正则”复杂。
错误信息需要指出哪个字段、哪里不符合要求、如何修正。使用可见文本与 aria-describedby 关联帮助或错误文案;错误不能只靠颜色区分。提交失败时保留用户已填写内容,将焦点移到错误摘要或第一个错误字段,异步校验状态使用合适的 live region 提示。
<label for="email">邮箱</label>
<input
id="email"
name="email"
type="email"
autocomplete="email"
required
aria-describedby="email-help email-error"
/>
<p id="email-help">用于发送登录验证码。</p>
<p id="email-error" aria-live="polite"></p>
如果使用 pattern,它按整个值进行匹配,正则边界和浏览器实现都应经过测试;不要把一个复杂、无法解释的表达式当作国际邮箱标准。浏览器原生校验、交互提示与服务器端规则应保持一致,但服务端仍是最终裁判。
密码字段不是复杂度竞赛
密码输入应支持密码管理器、粘贴和自动填充;登录使用 autocomplete="current-password",注册或修改使用 autocomplete="new-password"。不要强行禁止空格、Unicode 或密码管理器生成的字符串,也不要静默截断。合理的最小/最大长度由认证系统与所用密码哈希算法共同决定。
单纯要求必须同时有大小写、数字、符号的规则,常让人形成难记又重复的密码。更有效的策略是允许足够长的密码或口令短语、阻止常见或已泄漏密码、对认证尝试限速,并在服务端用 Argon2id、scrypt、bcrypt 或合规需要的 PBKDF2 等专用慢哈希保存密码。具体参数要在目标机器压测,不能用 SHA-256 直接保存密码。
强度仪表只是用户体验提示,不是熵的精确测量,也不能代替泄漏密码检查。若显示评分,应说明它只是估计并避免把密码发给第三方评分服务。密码确认字段用于发现输入错误;修改密码时应由服务端认证当前用户并限制尝试。
事件、错误与提交
不要只监听键盘 keyup:粘贴、移动端输入法、自动填充和辅助技术可能采用不同事件路径。以表单 submit 为主,按需在字段变化后做本地即时反馈;异步请求要显示忙碌状态、阻止重复提交,并处理超时、网络失败与服务器字段错误。
const form = document.querySelector('form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
if (!form.reportValidity()) return;
const data = new FormData(form);
const response = await fetch('/api/account/register', {
method: 'POST',
body: data,
credentials: 'same-origin',
});
if (!response.ok) {
// 将服务器返回的字段错误映射到表单;不回显密码。
return;
}
});
敏感认证表单还要遵循站点的 CSRF、Session、传输加密、重试和审计策略;前端不能把密码写进 URL、分析事件或日志。
上线前检查
- 键盘、触屏、屏幕阅读器和浏览器自动填充能否完成整条流程?
- 空值、异常字符、超长文本、重复提交和网络断开是否有清楚反馈?
- 使用 HTTP 客户端绕过页面时,服务端是否仍拒绝无效或越权数据?
- 密码是否不回显到日志、URL、错误追踪或第三方监控?
- 密码策略是否接受管理器和长口令,而非过度依赖字符组合评分?
参考:MDN Constraint validation、MDN input type=email、OWASP Authentication Cheat Sheet、OWASP Password Storage Cheat Sheet、WAI Forms Tutorial。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。