表单校验必须前后端双重保障:前端HTML5属性仅作体验优化,JS需监听submit事件并手动验证;后端须独立重验所有字段,与前端规则严格对齐,隐藏字段不可信。

表单数据完整性校验不能只靠前端,required、pattern 这类 HTML5 属性只是第一道体验关卡,真正起作用的是后端对每个字段的独立重验 —— 前端绕过太容易,浏览器开发者工具改个 disabled 或删掉 required 就能提交非法值。
HTML5 原生属性能做什么、不能做什么
它们适合快速建立基础约束,但别指望它们防住恶意输入:
-
required只检查是否为空,不校验内容有效性(比如填了test@test也能过type="email") -
pattern的正则在不同浏览器中行为略有差异,iOS Safari 对某些 Unicode 字符支持弱 -
minlength/maxlength是字符长度,不是字节数 —— 中文、emoji 可能被截断或校验失效 - 所有这些属性都依赖浏览器渲染和 JS 启用;禁用 JS 或用 curl 提交时,它们完全不生效
JavaScript 验证必须监听 submit 而非仅 input
实时 input 校验体验好,但容易漏掉关键路径:用户右键“粘贴”绕过事件、用自动填充工具跳过 blur、甚至直接调用 form.submit() 方法。真正可靠的拦截点只有一个:
- 给
form绑定submit事件,用e.preventDefault()阻止默认提交 - 逐个读取
form.elements,对每个字段调用自定义验证函数(不要只信checkValidity(),它不校验业务逻辑) - 密码确认类场景必须手动比对两个
value,pattern无法表达字段间依赖 - 错误提示要写入 DOM 元素(如
span.error),别只用alert()或console.log()
后端校验必须和前端规则严格对齐
前后端用不同正则、不同长度限制、不同空格处理逻辑,是线上数据脏乱的常见源头:
立即学习“前端免费学习笔记(深入)”;
- 邮箱校验:前端用
type="email"+ 简单正则,后端必须用 RFC 5322 兼容库(如 Python 的email-validator),不能只切分@ - 手机号:前端
pattern="^1[3-9]\d{9}$",后端需支持国际号(+86)、带分隔符格式,并做号码归属地/运营商校验 - 价格字段:前端显示
¥100.00,后端接收的可能是字符串"100.00"或数字100,必须统一转为定点数(如 cents)再入库 - 所有字符串字段必须做 trim() 和 null-byte 过滤,防止
"admin\0"绕过用户名唯一性检查
最常被忽略的一点:隐藏字段(如 <input type="hidden" name="price" value="999">)看似安全,但用户随时能用 DevTools 修改 —— 它们根本不能参与任何业务决策,价格、权限、状态等关键数据必须由后端从 session 或数据库重新查,而不是信任表单传来的任何值。



















