required仅校验非空,pattern受限且提示弱,可靠校验需javascript的test()配合trim()和setcustomvalidity(),后端校验是不可绕过的安全底线。

required 属性能解决“是否为空”的问题,但不能替代格式校验;pattern 是浏览器原生支持的正则入口,但写法受限、提示弱、移动端不可靠;真要稳,得用 JavaScript 的 test() 配合预处理和事件重置。
required 属性只管空不空,不管对不对
加了 required 的 <input>、<select></select>、<textarea></textarea> 在提交时会阻止空值提交,这是浏览器默认行为。但它完全不关心内容——比如邮箱字段填 “abc”、手机号填 “123”,只要非空就放行。
常见错误现象:
- 用户输入空格或换行符(
" ")也被判为“已填写” -
type="email"只校验基本结构(含 @ 和 .),不验证域名是否存在 - IE 10 及更早版本根本不支持
required,需 JS 兜底
所以 required 只是第一道门槛,不是终点。
pattern 属性怎么写才不白写
浏览器会自动给 pattern 值加上 ^ 和 $,你写的正则必须能“全字符串匹配”,且不能带修饰符(如 /g、/i)或字面量斜杠。
正确写法示例:
- 用户名:3–16 位字母数字下划线 →
pattern="[a-zA-Z0-9_]{3,16}" - 中国大陆手机号:→
pattern="1[3-9]d{9}"(注意没写^和$) - 末尾六位数字:→
pattern=".*[0-9]{6}$"(.*吃掉前面任意字符)
容易踩的坑:
- 写成
pattern="/1[3-9]d{9}/":斜杠被当作文本,永远不匹配 - 写成
pattern="^[a-z]+@.*$":某些 Safari 版本直接忽略整条规则 - 依赖
title提示:移动端 hover 不生效,用户根本看不到
JavaScript 的 test() 才是主力校验手段
复杂场景(如密码强度、前后端规则一致、实时反馈)必须用 RegExp.prototype.test()。它灵活、可控、可调试,还能配合 trim()、setCustomValidity() 和事件重置。
关键操作建议:
- 监听
input或blur事件,而非只等submit - 每次校验前先调用
element.setCustomValidity('')清除旧错误,否则会卡住提交 - 对输入值做
.trim()预处理,避免空格干扰 - 正则字面量优于构造函数:
/^1[3-9]d{9}$/.test(val)比new RegExp("^1[3-9]\d{9}$").test(val)更安全(不用双转义)
简短示例(手机号实时校验):
const phoneInput = document.querySelector('input[name="phone"]');
phoneInput.addEventListener('blur', function() {
const val = this.value.trim();
const re = /^1[3-9]d{9}$/;
if (!re.test(val)) {
this.setCustomValidity('请输入正确的中国大陆手机号');
} else {
this.setCustomValidity('');
}
});
后端校验不是“补充”,而是底线
所有前端校验(包括 required、pattern、JS test())都可被绕过:禁用 JS、改 HTML、抓包重发……
所以真正容易被忽略的是:
- 前后端正则必须完全一致,否则会出现“前端说 OK、后端拒收”的情况
- 后端不能只校验“非空”和“格式”,还要做长度截断、SQL 注入过滤、XSS 转义
- 错误响应应返回明确字段名和错误码,方便前端精准映射提示
没有后端校验的表单,就像没锁的保险柜——看着结实,其实一撬就开。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











