HTML 表单与验证
表单基础
HTML表单用于收集用户输入,包含各种输入控件。
基本表单结构
html
<form action="/submit" method="POST" enctype="multipart/form-data">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
<button type="submit">提交</button>
</form>表单属性
form 属性
html
<form action="/submit" method="POST" enctype="multipart/form-data"
target="_blank" autocomplete="on" novalidate>
<!-- 表单内容 -->
</form>action: 表单提交的URLmethod: 提交方法(GET/POST)enctype: 编码类型application/x-www-form-urlencoded: 默认multipart/form-data: 文件上传text/plain: 纯文本
target: 打开方式(_self/_blank/_parent/_top)autocomplete: 自动完成novalidate: 禁用浏览器验证
输入控件
1. 文本输入
html
<!-- 单行文本 -->
<input type="text" name="username" placeholder="请输入用户名"
maxlength="20" required>
<!-- 密码 -->
<input type="password" name="password" placeholder="请输入密码"
minlength="6" required>
<!-- 邮箱 -->
<input type="email" name="email" placeholder="请输入邮箱" required>
<!-- URL -->
<input type="url" name="website" placeholder="请输入网址">
<!-- 电话 -->
<input type="tel" name="phone" placeholder="请输入电话">
<!-- 搜索 -->
<input type="search" name="search" placeholder="搜索">
<!-- 多行文本 -->
<textarea name="message" rows="5" cols="40" placeholder="请输入留言"
maxlength="500" required></textarea>2. 数字输入
html
<!-- 数字 -->
<input type="number" name="age" min="0" max="120" step="1"
placeholder="年龄">
<!-- 范围 -->
<input type="range" name="volume" min="0" max="100" value="50">
<!-- 日期 -->
<input type="date" name="birthday">
<!-- 时间 -->
<input type="time" name="meeting-time">
<!-- 日期时间 -->
<input type="datetime-local" name="meeting-date">
<!-- 月份 -->
<input type="month" name="month">
<!-- 周 -->
<input type="week" name="week">3. 选择控件
html
<!-- 单选按钮 -->
<fieldset>
<legend>性别</legend>
<input type="radio" id="male" name="gender" value="male" checked>
<label for="male">男</label>
<input type="radio" id="female" name="gender" value="female">
<label for="female">女</label>
</fieldset>
<!-- 复选框 -->
<fieldset>
<legend>兴趣爱好</legend>
<input type="checkbox" id="reading" name="hobbies" value="reading">
<label for="reading">阅读</label>
<input type="checkbox" id="music" name="hobbies" value="music">
<label for="music">音乐</label>
<input type="checkbox" id="sports" name="hobbies" value="sports">
<label for="sports">运动</label>
</fieldset>
<!-- 下拉选择 -->
<select name="city" required>
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select>
<!-- 多选下拉 -->
<select name="skills" multiple size="4">
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="javascript">JavaScript</option>
<option value="python">Python</option>
</select>
<!-- 选项组 -->
<select name="category">
<optgroup label="前端">
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
</optgroup>
<optgroup label="后端">
<option value="python">Python</option>
<option value="java">Java</option>
<option value="node">Node.js</option>
</optgroup>
</select>4. 文件上传
html
<!-- 单文件上传 -->
<input type="file" name="avatar" accept="image/*" required>
<!-- 多文件上传 -->
<input type="file" name="files" multiple accept=".jpg,.png,.pdf">
<!-- 文件拖拽区域 -->
<div class="drop-zone">
<input type="file" name="file" id="file-input" hidden>
<label for="file-input">拖拽文件到此处或点击上传</label>
</div>5. 其他控件
html
<!-- 按钮 -->
<button type="submit">提交</button>
<button type="reset">重置</button>
<button type="button">普通按钮</button>
<!-- 隐藏字段 -->
<input type="hidden" name="user-id" value="123">
<!-- 颜色选择器 -->
<input type="color" name="theme-color" value="#ff0000">
<!-- 进度条 -->
<progress value="70" max="100">70%</progress>
<!-- 度量衡 -->
<meter value="0.6" min="0" max="1" low="0.2" high="0.8" optimum="0.5">60%</meter>
<!-- 输出 -->
<output name="result">计算结果</output>表单验证
HTML5 验证属性
html
<form novalidate>
<!-- 必填 -->
<input type="text" name="username" required>
<!-- 最小/最大长度 -->
<input type="password" name="password" minlength="6" maxlength="20">
<!-- 最小/最大值 -->
<input type="number" name="age" min="0" max="120">
<!-- 正则表达式 -->
<input type="text" name="phone" pattern="^1[3-9]\d{9}$"
placeholder="请输入手机号">
<!-- 邮箱格式 -->
<input type="email" name="email" required>
<!-- URL格式 -->
<input type="url" name="website" placeholder="https://example.com">
<!-- 自定义验证消息 -->
<input type="text" name="username" required
pattern="[a-zA-Z0-9_]{4,16}"
title="用户名必须是4-16位的字母、数字或下划线">
</form>验证状态
html
<form>
<input type="email" name="email" required>
<span class="error-message"></span>
</form>
<script>
const form = document.querySelector('form');
const emailInput = document.querySelector('input[name="email"]');
const errorMessage = document.querySelector('.error-message');
emailInput.addEventListener('input', function() {
if (this.validity.valid) {
errorMessage.textContent = '';
this.setCustomValidity('');
} else {
if (this.validity.valueMissing) {
errorMessage.textContent = '请输入邮箱地址';
} else if (this.validity.typeMismatch) {
errorMessage.textContent = '请输入有效的邮箱地址';
}
this.setCustomValidity('请输入有效的邮箱地址');
}
});
form.addEventListener('submit', function(e) {
if (!form.checkValidity()) {
e.preventDefault();
emailInput.reportValidity();
}
});
</script>自定义验证
html
<form id="myForm">
<input type="password" id="password" name="password" required>
<input type="password" id="confirmPassword" name="confirmPassword" required>
<button type="submit">提交</button>
</form>
<script>
const form = document.getElementById('myForm');
const password = document.getElementById('password');
const confirmPassword = document.getElementById('confirmPassword');
confirmPassword.addEventListener('input', function() {
if (this.value !== password.value) {
this.setCustomValidity('两次输入的密码不一致');
} else {
this.setCustomValidity('');
}
});
form.addEventListener('submit', function(e) {
if (!form.checkValidity()) {
e.preventDefault();
form.reportValidity();
}
});
</script>表单增强
自动完成
html
<form autocomplete="on">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" autocomplete="username">
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" autocomplete="email">
<label for="password">密码:</label>
<input type="password" id="password" name="password" autocomplete="new-password">
<label for="address">地址:</label>
<input type="text" id="address" name="address" autocomplete="street-address">
</form>禁用和只读
html
<!-- 禁用 -->
<input type="text" name="disabled" disabled>
<select name="disabled-select" disabled>
<option>选项1</option>
</select>
<button type="submit" disabled>提交</button>
<!-- 只读 -->
<input type="text" name="readonly" value="只读内容" readonly>
<textarea name="readonly-text" readonly>只读内容</textarea>表单分组
html
<form>
<fieldset>
<legend>个人信息</legend>
<label for="name">姓名:</label>
<input type="text" id="name" name="name">
<label for="age">年龄:</label>
<input type="number" id="age" name="age">
</fieldset>
<fieldset>
<legend>联系方式</legend>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email">
<label for="phone">电话:</label>
<input type="tel" id="phone" name="phone">
</fieldset>
</form>面试常见问题
1. GET 和 POST 的区别?
- GET: 参数在URL中,有长度限制,可缓存,可收藏
- POST: 参数在请求体中,无长度限制,不可缓存,更安全
html
<form action="/search" method="GET">
<input type="text" name="q">
<button type="submit">搜索</button>
</form>
<form action="/submit" method="POST">
<input type="text" name="data">
<button type="submit">提交</button>
</form>2. enctype 的三种类型?
application/x-www-form-urlencoded: 默认,URL编码multipart/form-data: 文件上传text/plain: 纯文本
html
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">上传</button>
</form>3. required 属性的作用?
required属性标记输入字段为必填,如果用户未填写,表单无法提交。
html
<input type="text" name="username" required>4. 如何禁用浏览器默认验证?
在form标签上添加novalidate属性。
html
<form novalidate>
<input type="email" name="email">
<button type="submit">提交</button>
</form>5. 如何实现密码确认验证?
使用JavaScript自定义验证,比较两次输入的密码是否一致。
javascript
const password = document.getElementById('password');
const confirmPassword = document.getElementById('confirmPassword');
confirmPassword.addEventListener('input', function() {
if (this.value !== password.value) {
this.setCustomValidity('两次输入的密码不一致');
} else {
this.setCustomValidity('');
}
});通过理解HTML表单的各种输入控件和验证机制,可以构建用户友好、安全可靠的表单界面。