前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库required pattern maxlength 约束验证
HTML语义与文档

HTML5 的 required、pattern、maxlength 这些验证属性是怎么工作的?

required 拦空值,pattern 检查非空输入的格式,maxlength 通常限制用户手工输入的长度。表单提交前浏览器会做约束验证;不合格就阻止提交,但脚本写入的超长值不能指望它替你拦住。

前端进阶之旅 · 一题精讲更新于 2026.09.29
HTML#语义与文档
先看核心答案读代码示例
理解线索

约束验证的三个角色

  1. 验证属性required、pattern、maxlength、min、max、type 等,告诉浏览器什么算合法
  2. ValidityState每个控件都有 validity 对象,包含 valueMissing、patternMismatch 等布尔字段
  3. checkValidity()手动触发校验并返回布尔值,不通过时触发 invalid 事件

maxlength 通常限制手工输入;脚本写入的超长值不会触发 tooLong 约束。

核心回答

先记住这个答案

浏览器内置了一套叫「约束验证」的机制。你在 <input> 或 <textarea> 上写 required、pattern、maxlength 这些属性,用户点提交按钮时浏览器会逐个检查。第一个不合法的控件会获得焦点,旁边弹出一段默认提示文字,同时 submit 事件不会触发。整个过程不需要 JavaScript 参与。

  • required 管空值,pattern 管格式
  • patternMismatch 随输入更新,默认气泡通常提交时出现
  • novalidate 或 submit() 跳过校验
  • 浏览器校验只防误填,防不了恶意提交,服务端校验不能省

每个属性管什么

required 最简单,控件值为空就不通过。<input type="text" required> 用户不填就提交不了。

pattern 接受一个正则表达式,浏览器会拿控件的值去匹配。注意浏览器会自动在两端加上 ^ 和 $,所以写 pattern="[0-9]{6}" 就是精确匹配 6 位数字,不用自己加锚点。pattern 只在控件有值时才校验,空值不报错,想同时拦空值要配合 required。

maxlength 的行为和前两个不同:浏览器通常会在用户输入时限制长度。脚本直接给 value 赋超长内容却不会触发 tooLong 约束,调用 checkValidity() 也不会替你兜底。这正是服务端必须独立校验长度的一个例子。

一个注册表单的写法HTML
<form>
  <label>手机号
    <input type="tel" required pattern="1[3-9]\d{9}"
           title="请输入 11 位手机号">
  </label>
  <label>昵称
    <input type="text" required maxlength="20"
           minlength="2">
  </label>
  <label>邀请码(选填)
    <input type="text" pattern="[A-Z0-9]{8}"
           title="8 位大写字母或数字">
  </label>
  <button type="submit">注册</button>
</form>

手机号同时用了 required 和 pattern,空值和格式不对都会被拦。邀请码只有 pattern 没有 required,不填可以提交,填了就必须符合格式。title 可以为输入规则提供提示,但各浏览器错误气泡的文案和呈现并不一致,重要说明应放在控件旁边。

用 JavaScript 扩展验证

浏览器默认气泡不便统一设计;若要在字段旁显示自己的文案,可以先关闭表单的交互式验证,在提交时主动检查,并把提示写到页面上。需要替换浏览器自身的验证消息时,才用 setCustomValidity(),错误修正后还要用空字符串清除旧消息。

自定义提示写法HTML
<form id="myForm" novalidate>
  <input id="phone" type="tel" required pattern="1[3-9]\d{9}">
  <span id="phone-error"></span>
  <button type="submit">提交</button>
</form>
<script>
  const form = document.getElementById('myForm')
  const phone = document.getElementById('phone')
  const error = document.getElementById('phone-error')
  form.addEventListener('submit', e => {
    error.textContent = '' // 每次提交前清掉旧提示
    if (!form.checkValidity()) {
      e.preventDefault()
      // validity 对象告诉你具体哪条没过
      if (phone.validity.valueMissing) error.textContent = '请填写手机号'
      else if (phone.validity.patternMismatch) error.textContent = '手机号格式不对'
    }
  })
</script>

表单加了 novalidate 后浏览器不再自动校验,提交时手动调 checkValidity() 来判断。每个控件的 validity 对象有十来个布尔字段,valueMissing 对应 required 没过,patternMismatch 对应 pattern 没过,tooLong 对应 maxlength 没过,可以根据不同的失败原因给不同提示。

浏览器校验和服务端校验的分工

浏览器校验只能防误填,防不了恶意提交。用户在 DevTools 里删掉 required 属性,或者直接用 curl 发请求,前端校验形同虚设。所以服务端必须再校验一遍,两边的规则保持一致。

浏览器校验的价值在于用户体验:不用等请求往返就能即时反馈,减少无效提交。服务端校验的价值在于安全:防止绕过前端直接提交脏数据。两层缺一不可。

回答前,多想一步

容易答错的地方

以为 pattern 的状态只在提交时更新
patternMismatch 和 CSS 的 :invalid 会随当前值变化;只是浏览器的默认错误气泡通常在提交等交互式验证时出现。想在用户输入过程中显示自己的错误文案,可监听 input 并读取 validity,还应避免用户未完成输入时就反复打断。
把 maxlength 和 max 搞混
maxlength 限制的是字符串长度,用在 <input type="text"> 和 <textarea> 上。max 限制的是数值大小,用在 <input type="number"> 上。写反了不会报错但也不会生效。
试着用自己的话回答

面试官还会怎么问?

type="email" 和 type="url" 自带验证吗?

自带。浏览器会按内置的格式规则校验,不用再写 pattern。但内置的 email 校验比较宽松,比如 a@b 也能通过,如果产品要求更严格的格式,还得加 pattern 或服务端校验。

CSS 的 :valid 和 :invalid 是怎么配合验证属性工作的?

浏览器会根据约束验证的结果实时切换这两个伪类。控件当前值合法就匹配 :valid,不合法就匹配 :invalid。配合 required,一个空的必填框一打开页面就是 :invalid 状态,如果不想一上来就显示红框,可以用 :user-invalid(需要用户交互后才生效)。

用 JavaScript 调 form.submit() 会触发验证吗?

不会。form.submit() 会跳过约束验证直接提交。想在 JS 里提交又想走验证流程,应该用 form.requestSubmit(),它和用户点提交按钮的行为一致。

从一道题,走向一组知识

把知识连起来

语义与文档

script 的 defer 和 async 什么时候执行?

表单验证脚本若要查找后面的控件,可用 defer 等 DOM 解析结束后再注册提交监听。

语义与文档

select 选项很多时,optgroup 怎么分组?

带 required 的单选 <select> 若有空值占位项,它应在 <optgroup> 外才能按占位项规则识别。

参考资料

  • HTML:语义与文档参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 每个属性管什么
  3. 用 JavaScript 扩展验证
  4. 浏览器校验和服务端校验的分工
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑