required属性仅对、、生效,且须在原生表单提交、非disabled/readonly、含form包裹下才触发校验;checkbox/radio的required指必须选择而非填值;服务端必须二次校验,因前端校验可被绕过。

required 属性加在哪些标签上才起作用
只对 <input>、<select></select>、<textarea></textarea> 三类标签生效,其他如 <label></label>、<div>、<code><span></span> 加了也白加。
常见错误写法:
-
<label required>姓名</label><input type="text" name="name">——required在<label></label>上无效 -
<input type="hidden" name="token" required>——type="hidden"浏览器直接忽略required -
<input type="range" required>或<input type="color" required>—— 空值语义模糊,不触发校验
正确写法示例:
<input type="text" name="name" required><select name="city" required><option value="">请选择城市</option> <option value="bj">北京</option></select><textarea name="desc" required></textarea>
为什么加了 required 还能提交成功
不是属性没写对,而是校验根本没启动。浏览器只在「原生表单提交」时检查,其他方式都会绕过。
- 按钮用了
<button type="button"></button>或没写type(默认是button),不是submit - JS 里调了
form.submit()—— 这个调用跳过所有原生校验 - 表单外层没包
<form></form>,required失去上下文,完全不工作 - 控件被设为
disabled或readonly,哪怕有required也被跳过 - 移动端旧版 Safari(≤15.4)对
type="date"或type="file"的空值判断不准,可能返回默认日期或空字符串但未触发校验
checkbox 和 radio 的 required 行为很特别
它们的“必填”不是指“填内容”,而是“必须做选择”。逻辑和文本类输入完全不同。
-
<input type="checkbox" name="agree" required>:用户必须勾选,否则提交失败 -
<input type="radio" name="gender" value="m" required>:同一name下任意一个加required即可,表示该组至少选一个 - 注意:如果 radio 组里所有选项都带
checked,哪怕没加required也能过;但加了required后,哪怕预设了checked,用户取消再提交也会失败 - 不要给
checkbox设value=""再加required——它只看是否勾选,不看 value 是什么
服务端永远要二次校验,前端拦不住任何真实请求
用户禁用 JS、删掉 HTML 属性、用 curl 直接发请求,required 彻底失效。后端收到的数据可能包括:
- 空字符串
"" - 纯空格
" "或制表符"\t\n"—— 前端required不 trim,服务端得自己处理 -
null或缺失字段(比如用户删了整个<input>标签) - 甚至
"000"、"N/A"这类业务上算“空”的值,required也无感
最常被忽略的一点:前后端对“空”的定义必须一致。比如手机号字段,"123" 算不算空?"0000000000" 怎么判?这些不能靠 required 解决,得靠后端规则 + 前端 pattern 或自定义 JS 配合。











