autocomplete="cc-number"会主动触发浏览器信用卡填充逻辑,禁用应改用new-password、one-time-code等非支付语义值,并辅以隐藏干扰字段、动态name及清空密码记录等综合手段。

autocomplete="cc-number"反而会触发信用卡自动填充
浏览器看到 autocomplete="cc-number" 会立刻激活信用卡识别逻辑,不仅可能填充已有卡号,还会在表单提交后弹出“保存信用卡”提示。这不是你想要的“禁用”,而是明示“请来填卡”。对银行卡号、CVV、有效期等字段,必须避免所有标准支付语义值:cc-number、cc-csc、cc-exp、cc-name。
可行替代方案包括:
-
autocomplete="new-password":Chrome 等主流浏览器会将其视为非支付上下文,不触发卡信息保存 -
autocomplete="one-time-code":适用于 CVV,部分浏览器识别为临时验证码,不存档 -
autocomplete="section-foo shipping tel":用空格拼接无效组合,破坏内置匹配规则 -
autocomplete="off":虽已不被 Chrome 尊重,但 Safari 和旧 WebView 仍响应,可作兜底
隐藏同名干扰字段比单纯写 autocomplete 更可靠
浏览器自动填充时,通常只对 DOM 中第一个 type="password" 或疑似敏感字段执行填充。你可以利用这个行为,在真实输入框前插入一个不可见的干扰项:
<input type="password" style="display:none" autocomplete="new-password">
关键点:
- 必须用
style="display:none",visibility:hidden或opacity:0仍可能被识别 - 该元素需在 DOM 中物理位置位于真实字段之前
- 不要设
name或设为无意义值(如name="dummy"),避免污染表单提交 - 此方案纯 HTML,不依赖 JS,兼容性极佳,是金融级表单的常用保底手段
动态生成 name/id 是绕过启发式匹配的核心手段
浏览器不光看 autocomplete,更依赖 name、id、label 文本做启发式判断。写 name="cardNumber" 或 id="cvv-input",等于直接告诉浏览器“这是卡号/CVV”。
真正有效的做法是让字段名失去语义:
- 服务端每次渲染生成随机 name,例如
name="fld_8a3f92",提交时再映射回业务字段 - 前端 JS 动态设置
name和id,确保初始 HTML 中不包含敏感关键词 - 避免在 class、placeholder、aria-label 中出现
card、cvv、expiry等词 - 若框架强制要求固定 name(如某些表单库),至少把
autocomplete设为new-password或nope
Chrome 120+ 要求新旧密码成对才认 new-password
从 Chrome 120 开始,autocomplete="new-password" 只有在表单中同时存在 autocomplete="current-password" 字段时才会被认真对待。如果你只有“设置新密码”页,没有旧密码输入框,Chrome 会直接忽略它,并可能强行填入上次保存的密码。
应对方式有限但明确:
- 修改密码流程必须包含
<input type="password" autocomplete="current-password">,哪怕它只用于占位或校验(后端可忽略该字段值) - 注册页无需旧密码字段,此时
new-password效果打折,应叠加隐藏干扰字段 + 动态 name - 测试前务必清空 Chrome 的 Application → Passwords 面板中该域名的记录,否则永远在验证旧状态
真正难缠的不是属性怎么写,而是浏览器把“自动填密码”当作安全功能来实现——你控制不了它是否填充,只能控制它往哪个字段填、填什么内容、以及填完后要不要保存。











