HTML 表单控件与校验
梳理常用表单控件类型与约束校验 API 的能力边界,说明原生校验与 JS/服务端校验如何分层。
#type / concept
#status / growing
#tech / dev / frontend
#resource / html
[!info] 关联笔记
HTML 表单控件与校验
这个概念为什么出现
只靠“提交时 fetch + alert”会漏掉:
- 邮箱格式、数字范围、必填
- 移动端合适键盘(
inputmode/type=email) - 无 JS 时的第一道防线
HTML 控件类型 + 约束校验把常见规则下沉到平台。
[!abstract] 一句话理解 选对控件类型是交互与数据质量的一部分;
required/min/max/pattern等是浏览器内建校验,但不是业务规则引擎,更不能替代服务端。
最小可运行示例
场景:新建 SKU 基础信息
<form id="sku-form">
<label for="sku">SKU 编码</label>
<input
id="sku"
name="sku"
required
pattern="[A-Z0-9-]{3,20}"
title="3-20 位大写字母、数字或短横线"
autocomplete="off"
/>
<label for="qty">安全库存</label>
<input id="qty" name="safetyStock" type="number" min="0" max="99999" required />
<label for="email">通知邮箱</label>
<input id="email" name="notifyEmail" type="email" required />
<button type="submit">创建</button>
</form>
<script>
// 教学点:可在提交前读 validity,做统一错误区,而不是去掉原生校验
const form = document.getElementById('sku-form')
form.addEventListener('submit', (event) => {
if (!form.checkValidity()) {
event.preventDefault()
// 让浏览器显示原生提示或改为自定义 UI
form.reportValidity()
return
}
// 通过后再走 fetch...
})
</script>
期望:空值/非法 SKU/非法邮箱时提交被拦住;type=number 在支持的移动浏览器上更易输入数字。
结合场景关注点
pattern是前端体验,可被绕过。type=email等校验规则因浏览器而细节差异。- 自定义 UI 时仍可用
setCustomValidity。
核心模型
控件选型(压缩)
| 需求 | 优先 |
|---|---|
| 短文本 | type=text |
| 密码 | password |
| 邮箱/URL/电话 | email/url/tel |
| 数字 | number 或文本+输入策略 |
| 选项 | select/radio/checkbox |
| 文件 | file + form enctype |
| 多行 | textarea |
约束校验要点
- 约束属性:
requiredminmaxminlengthmaxlengthpatternstep - JS API:
checkValidityreportValiditysetCustomValidityvalidity - CSS 伪类:
:valid:invalid:required(样式见 CSS 表单笔记)
边界
- 跨字段(“结束日期 > 开始日期”)原生表达弱,需 JS。
- 关闭原生提示却不重建可访问错误 = 退步。
novalidate常用于完全自定义校验,但要自己负责完整性。
常见误区
[!warning] 常见误区:客户端校验通过 = 数据安全 攻击者可不经浏览器直接打 API。服务端校验强制。
工程实践
- 错误文本与控件
aria-describedby关联。 - 失败时焦点落到第一个无效控件。
- 密码/隐私字段注意
autocomplete值。
本节总结
控件类型与原生校验是平台赠品;把它们当作第一层,把业务规则与安全放在 JS/服务端上层。
自测题
- 何时用
setCustomValidity? - 为什么
pattern不能当安全策略?
参考答案
- 原生约束表达不了或要统一文案/跨字段错误时。
- 可被绕过;只改善输入体验与快速反馈。
延伸阅读
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Constraint validation | MDN | API |
| input types | MDN | 控件 |