required属性仅对特定原生控件有效,如text、email、textarea、select、checkbox、radio和file(ios safari≤15.4有兼容问题),且不校验空格、换行等空白字符;它只在submit按钮点击或回车时触发,无法替代服务端校验。

required 属性不是万能开关,它只在特定控件、特定提交方式下生效,且空格、换行、制表符都被视为“已填写”——想靠它拦住用户乱填或绕过校验,基本没戏。
哪些表单元素加 required 才真起作用
浏览器只对明确具备“值可为空”语义的原生控件做校验:
-
<input type="text">、<input type="email">、<input type="tel">、<input type="number">、<input type="date">、<input type="file">(注意 iOS Safari ≤15.4 有兼容问题) -
<textarea></textarea>(哪怕只填一个空格也通过) -
<select></select>(必须带一个<option value=""></option>,且不能加selected) -
<input type="checkbox">和<input type="radio">(前者未勾选即失败;后者需至少一个选项被选中,且所有同名radio中不能全带checked)
以下写法完全无效:<input type="hidden" required>、<input type="range" required>、<div contenteditable="true" required>、任何第三方封装组件(如 Ant Design 的 <code>Input),除非显式透传 required 到底层 input。
required 怎么判断“空”?不同 type 行为差异极大
它不调用 .trim(),也不验证语义合法性,只看底层值是否为空字符串或未选中状态:
-
type="text":填" "、"\t"、"\n"都算“已填”,required不拦 -
type="email":填"@"或"test@.com"也能过,格式校验靠type自身或pattern -
type="checkbox":未勾选即失败;若写了checked,默认满足,必填逻辑失效 -
type="select":首个<option value=""></option>若同时带selected,用户不操作也能绕过 -
type="file":iOS Safari ≤15.4 存在校验不触发问题,需 JS 兜底
为什么点了提交按钮却没反应或直接跳过了校验
required 只在两个时机自动触发校验:
- 用户点击
<button type="submit"></button>或<input type="submit"> - 在可编辑字段内按回车(前提是该字段是表单内第一个可聚焦的控件)
其他情况一律不触发:
- 用
<button type="button"></button>调form.submit()—— 完全绕过校验 - JS 中监听
submit事件并执行了e.preventDefault(),但没手动调form.checkValidity()或form.reportValidity()—— 没提示也没提交 - 按钮写了
formnovalidate—— 显式禁用所有校验 - 动态渲染的元素(如 Vue/React 中
v-if或useState切换后插入的控件)—— 属性存在但浏览器未注册校验逻辑
服务端二次校验不是可选项,而是强制项
required 是纯前端拦截,仅用于用户体验优化。它无法防止:
- 用户禁用 JavaScript 后直接提交
- 用 Postman、curl 或脚本绕过页面发起请求
- 修改 DOM 后手动触发
form.submit()
所以后端收到数据时,必须独立检查每个 required 字段是否为空字符串、null、undefined 或仅含空白字符(此时才应真正拒绝)。别信前端传来的任何“已校验”信号。











