先记住这个答案
浏览器将输入值按等效于内部正则的算法校验,空字符串或单个格式正确的邮箱可通过;添加 multiple 后支持逗号分隔多个。它允许加号、子域名,但域名部分不能为空且字符受限定,也不自动接受非 ASCII 国际化邮箱。真实可用性必须依赖服务器端二次验证,否则可被绕过。
- 邮箱仅做结构校验,不验证存在
- 可用 pattern 加强域名限制
- multiple 以逗号分隔多个地址
内部正则与约束验证
浏览器在提交前会对 email 输入执行一套与正则等效的算法,要求值为空串或匹配 username@host 模式。本地部分允许字母数字及可能出现在邮箱名里的 ASCII 符号,主机部分则只接受字母、数字、连字符与点,且每个标签不得以连字符开头或结尾。由于算法的宽松性,像 a@b 这样没有点分隔的地址也能通过校验。
约束验证 API 会把 type 的格式规则与 required、minlength、pattern 等属性合并计算。在不满足约束时触发 invalid 事件并阻止表单提交,同时暴露 :invalid 等 CSS 选择器便于样式反馈。开发者可调用 setCustomValidity 自定义错误信息,但必须清楚这种校验可被用户轻易篡改。
公司域名与加号过滤场景
某企业注册页想只接收本公司的员工邮箱,允许前缀带加号区分用途,比如 alice+ops@company.com,并允许子域名 sub.company.com。默认的 email 校验已允许多级域名和加号,但无法限定域名来源,因此需要在 input 上附加 pattern 属性,例如 pattern="[\w.!#$%&'*+/=?^`{|}~-]+@(?:sub.)?company.com",这样只有匹配该正则的地址才能通过。
例如,alice+ops@company.com 符合内置校验,因为加号属于合法本地字符;而 alice@evil-company.com 因不匹配 pattern 被拒绝。若输入 company.com. 带尾点时,基础校验先判失败,pattern 不会执行。实际表单需为 pattern 添加 title 属性,提供统一的中文提示,否则浏览器会显示默认的英文格式错误。
边界值与国际化的失效点
边界值需要特别关注的是空字符串:未设置 required 时它是合法值,设置后则变为非法。启用 multiple 后,多个地址必须以逗号分隔且可带任意空白,但尾逗号会失败。输入中出现的空白(包括首尾)都会导致校验失败,比如 a b@c.com 无效,浏览器不会自动去除多余空格。
国际化邮箱是常见陷阱,因为内置正则只匹配 ASCII,直接输入 用户@例子.中国 不通过,浏览器也不会进行 punycode 转换。若要支持这种 IDN,需要改用 type="text" 并在服务器端做国际化处理;单纯依赖 pattern 不能放宽内置的 email 格式验证。另外,单标签主机如 a@b 能通过,但多数服务会拒绝,业务上需要额外正则强制至少包含一个点。
容易答错的地方
- 误以为会检查邮箱真实性
- 浏览器只检查字符串格式,不会查询 DNS 或发信验证,因此 a@b 也能通过。真实性必须靠服务器发送确认邮件等方式确认,而仅依赖前端校验会被用户篡改绕过。
- 分不清 multiple 的分隔符
- multiple 属性规定只能用逗号分隔地址,分号或空格都会被当作整体内容导致校验失败。若需要分号分隔,必须用 pattern 定义或改用 text 类型自己解析。
面试官还会怎么问?
如何强制邮箱非空?
为 input 添加 required 属性后,空字符串会被视为校验失败。可以再配合 minlength 和 maxlength 控制字符长度,但格式仍先按内置正则检查。
既然内置允许 + 和点,为什么还要写 pattern?
内置正则对本地部分不限制连续点或首尾点,例如 ..@example.com 也能通过,但实际运维中不允许。pattern 可以收紧规则,比如限定本地部分必须以字母开头。
如何让用户看到统一的校验提示?
使用 title 属性提供自定义描述,或监听 invalid 事件并用 setCustomValidity 设置消息。注意 setCustomValidity 必须传空字符串才能恢复默认状态。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。