required属性仅在原生表单提交时生效,若用fetch/axios、event.preventdefault()未校验、button类型错误、input未嵌套form、webview兼容性差或缺少name属性,均会导致空提交;pattern需与required配合使用且注意正则锚定;后端必须独立校验,因前端验证可被绕过。

required 属性是最直接、浏览器原生支持的防空手段,但它只在表单通过原生方式提交时生效——比如点击 <input type="submit"> 或回车触发表单提交。如果用了 fetch()、axios 或手动调用 event.preventDefault() 后没做校验,它就完全不拦。
为什么加了 required 还能空提交?
常见错误场景包括:
- 提交按钮写成
<button type="button"></button>而非<button type="submit"></button>或<input type="submit"> - 表单监听了
submit事件,但第一行就是event.preventDefault(),后续又没调用form.checkValidity() - 移动端 WebView(如旧版微信内置浏览器)对
required支持不全,需 JS 补位 -
<input>没包在<form></form>里,或form缺少method和action,导致浏览器不触发原生验证逻辑
pattern + required 组合验证更可靠
pattern 本身不防空,但和 required 配合可强制“非空且符合格式”。注意两点:
- 浏览器会自动给
pattern加上^和$锚定,写pattern="[a-z]{2,10}"等价于^[a-z]{2,10}$,不是“包含”而是“必须完全匹配” - 中文正则如
[\u4e00-\u9fa5]{2,10}在部分安卓浏览器中失效,建议降级为 JS 校验,或改用minlength="2"+required先保底线 -
title属性必须配pattern才显示提示,否则验证失败时只弹默认英文文案
后端收不到字段?先查 name 属性
前端加了 required,但 PHP 的 $_POST 或 Node.js 的 req.body 里根本没这个键——大概率是 <input> 缺了 name 属性。HTML 表单只提交带 name 的控件,id 或 class 不参与传输。
- 空
name、纯空格name=" "、或仅含特殊字符如name="*"都无效 -
type="checkbox"或type="radio"不勾选时默认不提交,若后端依赖该字段存在,得用 hidden input 补默认值,或 JS 提交前判断并补值 - 多个同名
name的 checkbox,浏览器会以逗号分隔提交(如hobby=reading,swimming),后端需按约定解析
真正容易被忽略的是:前端所有验证都只是体验层,required 不等于“后端可跳过校验”,它连网络请求都拦不住——用户禁用 JS、用 curl 直发、或改 DOM 后提交,数据照样进后端。所以 name 正确 + 前端提示 + 后端严格校验,三者缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











