支付密码输入框必须用并配合前端校验、防粘贴、实时比对、哈希加密及ios聚焦修复:需限制长度、校验强度、禁用右键、trim后逐字符比对、web crypto哈希后清空明文、延迟聚焦防ios失效。

支付密码输入框必须用 <input type="password">,但别只靠它
浏览器原生的 type="password" 能隐藏字符,但它不阻止复制粘贴、不限制长度、不校验强度,更不会防键盘记录。真实场景中,用户可能粘贴弱密码(如 "123456"),或连续按同一键("aaaaaa"),这些都得前端拦截。
实操建议:
- 用
inputmode="numeric"唤起数字键盘(移动端友好),但别设pattern="[0-9]*"—— 它在部分安卓机上会禁用粘贴 - 监听
input事件做实时校验,而非只等表单提交:检查长度(通常为 6 位)、是否全数字、是否含重复/顺序数字(如"123456"或"111111") - 禁用右键菜单和长按选中:加
oncontextmenu="return false"和onselectstart="return false"(iOS Safari 需额外加-webkit-user-select: none)
两次输入必须逐字符比对,不能只用 ===
用户设置支付密码时几乎都要求“确认密码”字段。常见错误是把两个 <input> 的 .value 直接用 === 比较 —— 看似没问题,但一旦用户在末尾多敲一个空格("123456 " vs "123456"),校验就静默失败。
实操建议:
- 比对前统一用
.trim()去首尾空格,且强制转字符串:String(input1.value).trim() === String(input2.value).trim() - 不要仅依赖前端比对:后端仍需校验两次传入的密文是否一致(防止绕过 JS)
- 视觉反馈要即时:输入第二个框时就触发比对,不匹配立刻标红边框 + 显示“两次输入不一致”,别等到点“确定”才提示
密码不能明文传输,form 提交前必须哈希
支付密码属于高敏感字段,HTML 表单如果直接 method="POST" 发送原始值,中间任何环节(代理、CDN、日志)都可能泄露。哪怕用了 HTTPS,服务端日志也可能误记明文。
实操建议:
- 用 Web Crypto API 在前端做一次不可逆哈希(推荐
SHA-256):await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)) - 避免用第三方 JS 库做哈希(如 CryptoJS):增加包体积,且部分库在 IE 或旧安卓 WebView 中行为不一致
- 哈希后的值作为新字段提交,原密码
<input>提交前清空其.value,防止被 console 或调试工具意外捕获
页面加载后自动聚焦第一个密码框,但 iOS Safari 有坑
为了体验连贯,多数支付密码页会在 DOMContentLoaded 后调用 input1.focus()。但在 iOS Safari 上,如果页面未完全渲染(比如 DOM 尚未 attach 到 document),focus() 会被静默忽略;更麻烦的是,若用户刚从其他 App 切换回来,首次 focus() 可能触发键盘却无光标。
实操建议:
- 用
setTimeout(() => input1.focus(), 300)延迟执行,避开 iOS 渲染队列问题 - 加兜底逻辑:监听
touchstart或click事件,若用户手动点过页面任意位置,再尝试聚焦(iOS 允许用户交互后的 focus) - 禁止在
autofocus属性上偷懒:<input autofocus>在微信内置浏览器里常失效,且无法控制聚焦时机
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











