novalidate 是布尔型 html 属性,加在 上即禁用浏览器原生验证;它不依赖 js,novalidate="true" 冗余且不规范;启用后 submit 事件仍触发,需手动校验并调用 preventdefault();reportvalidity() 不受其影响;服务端必须重复校验。

novalidate 是表单属性,不是 JavaScript 方法
很多人误以为 novalidate 是要调用的函数或需要配合 JS 才生效,其实它就是一个布尔型 HTML 属性,加在 <form></form> 标签上就直接禁用浏览器原生表单验证(比如 required、type="email" 的校验弹窗)。
常见错误是写成 novalidate="true" 或 novalidate="false" —— 这不对。HTML 布尔属性只要存在即为 true,删掉就为 false。
-
<form novalidate></form>✅ 禁用验证 -
<form novalidate="novalidate"></form>✅ 也有效,但冗余 -
<form novalidate="true"></form>❌ 浏览器会把它当字符串值,但依然生效(属于意外兼容,别依赖) -
<form></form>✅ 默认启用验证
novalidate 和 submit 事件的关系
加了 novalidate 后,点击提交按钮不会触发浏览器的阻断式校验,但 submit 事件仍会正常触发 —— 这正是你手动做自定义校验的入口。
容易踩的坑:有人加了 novalidate 就以为“不用管校验了”,结果后端被空数据打穿。其实只是把校验时机从浏览器前置移到了 JS 里。
- 必须监听
form.addEventListener('submit', handler)自己检查字段 - 检查不通过时要调用
event.preventDefault()阻止提交 - 别忘了给用户反馈(比如高亮错误字段、显示提示文案)
novalidate 不影响 input.reportValidity() 的行为
即使表单有 novalidate,单个 <input> 元素调用 reportValidity() 依然会触发原生校验 UI(红框 + 提示气泡)。这个方法不看父表单是否禁用验证。
这意味着你可以混合使用:表单整体跳过自动校验,但在特定操作(如失焦、保存草稿)时对某个字段手动触发校验。
-
document.querySelector('#email').reportValidity()→ 仍会弹原生提示 -
form.checkValidity()→ 返回false如果字段不合法,但不会显示 UI - 两者可搭配:先
checkValidity()判断,再按需调reportValidity()
服务端永远不能信任 novalidate
novalidate 只作用于前端渲染层,对网络请求完全无影响。恶意用户删掉这个属性、绕过 JS、甚至直接发 POST 请求,都能把非法数据送过来。
所以它只是改善用户体验的开关,不是安全机制。
- 前端校验用于即时反馈,提升交互流畅度
- 后端必须重复执行等价校验逻辑(比如邮箱格式、必填项非空)
- 前后端校验规则最好共用同一套正则或 Schema(例如用 Zod 定义 schema,前后端复用)
novalidate 往往和一套自定义校验库(比如 Formik、React Hook Form)配套出现,而不是单独存在。单独加它却没补上 JS 校验,等于只拆了保险丝,没换新电路。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











