formnovalidate是布尔属性,仅对type="submit"的button或input有效,点击时跳过浏览器原生校验(如required、type="email")但仍触发submit事件;普通submit按钮则会强制执行原生校验并拦截无效提交。

formnovalidate 是什么,它和普通 submit 有什么本质区别
formnovalidate 是 HTML 表单按钮的布尔属性,作用是**跳过当前表单的原生验证逻辑(比如 required、type="email"、pattern 等)**,但依然会触发表单的 submit 事件,并提交数据到 action 指定地址(或由 JS 拦截)。它不是“禁用验证”,而是“本次提交不触发验证”——这点常被误解为“绕过校验直接发请求”,实际它只影响浏览器原生约束检查,不影响你手写的 JS 校验逻辑。
常见错误现象:点了带 formnovalidate 的按钮,后端收到空字段或非法值,误以为是属性失效;其实是 JS 没做兜底校验,或者后端没做二次校验。
- 必须配合
type="submit"才生效,type="button"加了也没用 - 它不会阻止
onsubmit事件,也不会跳过event.preventDefault() - 如果表单里有多个 submit 按钮,只有被点击的那个按钮的
formnovalidate生效
如何用 formnovalidate 实现草稿保存 + 正式提交双通道
核心思路是:用两个按钮共用一个 <form></form>,一个带 formnovalidate 走草稿接口,一个不带走正式提交接口。关键在于区分提交意图,而不是靠后端判断字段是否填满。
典型场景:编辑页含大量字段(如文章编辑、订单配置),用户可能中途离开,需保留未完成内容;但正式提交时必须校验完整性与合法性。
- 草稿按钮写法:
<button type="submit" formnovalidate name="save_type" value="draft">保存草稿</button> - 正式提交按钮写法:
<button type="submit" name="save_type" value="publish">发布</button> - 后端通过
save_type字段区分处理路径,而非依赖字段是否为空 - 前端 JS 可在
submit事件中根据event.submitter.value判断是哪个按钮触发,决定是否运行完整校验逻辑
formnovalidate 下容易忽略的兼容性与副作用
它在所有现代浏览器中都支持(Chrome 10+、Firefox 4+、Safari 5.1+、Edge 12+),但有两个隐蔽坑点:
- 如果表单用了
novalidate全局禁用验证,formnovalidate就失去意义——因为本来就不校验,没必要再“跳过”一次 - 某些 UI 库(如 Ant Design、Element Plus)封装的
Button组件默认把type设为"button",直接加formnovalidate无效,必须显式设置htmlType="submit"或透传type="submit" - 移动端 Safari 对
formnovalidate的 focus 行为偶有异常(比如点击后光标未移出输入框),建议草稿按钮提交后主动blur()当前焦点元素
草稿保存时要不要清空验证状态
不要自动清空。用户点了“保存草稿”,不代表他放弃当前填写的内容或错误提示——相反,保留红色边框、错误文案能帮助他意识到哪些字段还没填对,下次回来可继续补全。
真正要做的,是在草稿提交成功后,仅重置表单的“脏状态”(比如清除 data-dirty 标记),但保留所有 input 值和验证 UI。正式提交成功后才调用 form.reset() 或清空字段。
- 避免在
formnovalidate提交后调用form.checkValidity()—— 它返回false但无意义,且可能干扰 UI 状态 - 若用
Constraint Validation API手动标记错误,草稿提交时无需调用setCustomValidity(""),否则会隐藏本该保留的提示 - 后端返回草稿保存成功响应后,可更新页面标题或加个轻提示:“草稿已保存”,别弹 success toast 干扰用户继续编辑
formnovalidate 只解决浏览器层的一道门,门后怎么走,还得靠你明确划分逻辑边界。











