HTML表单提交与编码
表单提交是前后端数据交互的核心方式,理解提交流制至关重要。
method提交方法
GET方法
HTML
<form method="get" action="/search">
<input type="text" name="q">
<button type="submit">搜索</button>
</form>
- 数据附加在URL后:
/search?q=keyword - 数据可见,不安全
- 有长度限制(约2KB-8KB)
- 可被缓存、收藏
- 适合查询、搜索
POST方法
HTML
<form method="post" action="/login">
<input type="text" name="username">
<input type="password" name="password">
<button type="submit">登录</button>
</form>
- 数据在请求体中
- 数据不可见,较安全
- 无长度限制
- 不会被缓存
- 适合登录、上传、数据修改
方法对比
| 特性 | GET | POST |
|---|---|---|
| 数据位置 | URL参数 | 请求体 |
| 安全性 | 低 | 较高 |
| 数据量 | 受限 | 无限制 |
| 缓存 | 支持 | 不支持 |
| 书签 | 可收藏 | 不可收藏 |
| 幂等性 | 是 | 否 |
enctype编码类型
application/x-www-form-urlencoded(默认)
HTML
<form method="post" enctype="application/x-www-form-urlencoded">
<input type="text" name="username" value="张三">
<input type="text" name="city" value="北京">
</form>
提交数据格式:
HTML
username=%E5%BC%A0%E4%B8%89&city=%E5%8C%97%E4%BA%AC
- 键值对形式:
key=value&key2=value2 - 特殊字符URL编码
- 适合普通文本数据
multipart/form-data
HTML
<form method="post" enctype="multipart/form-data">
<input type="text" name="username">
<input type="file" name="avatar">
<button type="submit">上传</button>
</form>
提交数据格式:
HTML
------WebKitFormBoundary
Content-Disposition: form-data; name="username"
张三
------WebKitFormBoundary
Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
Content-Type: image/jpeg
[二进制数据]
------WebKitFormBoundary--
- 必须用于文件上传
- 数据分块传输
- 每个字段独立编码
text/plain
HTML
<form method="post" enctype="text/plain">
<input type="text" name="message">
</form>
提交数据格式:
HTML
message=hello world
- 纯文本格式,无编码
- 很少使用
- 仅用于调试
编码类型选择
| 场景 | enctype |
|---|---|
| 普通表单 | application/x-www-form-urlencoded |
| 文件上传 | multipart/form-data |
| 纯文本(调试) | text/plain |
target目标窗口
值说明
HTML
<form action="/submit" target="_self">
<!-- 默认,当前窗口打开 -->
</form>
| 值 | 说明 |
|---|---|
_self | 当前窗口(默认) |
_blank | 新窗口/标签页 |
_parent | 父级框架 |
_top | 顶级窗口 |
framename | 指定iframe名称 |
新窗口提交
HTML
<form action="/preview" target="_blank">
<input type="text" name="content">
<button type="submit">预览</button>
</form>
iframe目标
HTML
<iframe name="result"></iframe>
<form action="/process" target="result">
<input type="text" name="data">
<button type="submit">提交到iframe</button>
</form>
action与提交控制
action属性
HTML
<!-- 指定URL -->
<form action="/api/submit">
<!-- 相对URL -->
<form action="submit.php">
<!-- 当前页面 -->
<form action="">
<!-- 省略action,默认当前页面 -->
<form>
formaction覆盖
HTML
<form action="/default">
<input type="text" name="data">
<button type="submit">默认提交</button>
<button type="submit" formaction="/save">保存</button>
<button type="submit" formaction="/preview">预览</button>
</form>
formmethod覆盖
JavaScript
<form method="post" action="/api">
<input type="text" name="query">
<button type="submit">POST提交</button>
<button type="submit" formmethod="get" formaction="/search">GET搜索</button>
</form>
表单属性覆盖
表单控件可覆盖form的属性:
text
<form action="/default" method="post" enctype="application/x-www-form-urlencoded">
<input type="text" name="data">
<!-- 覆盖提交方式 -->
<button type="submit" formmethod="get">GET提交</button>
<!-- 覆盖编码类型 -->
<input type="file" name="file" formenctype="multipart/form-data">
<button type="submit">文件上传</button>
<!-- 覆盖目标 -->
<button type="submit" formtarget="_blank">新窗口提交</button>
<!-- 跳过验证 -->
<button type="submit" formnovalidate>跳过验证</button>
</form>
| 属性 | 说明 |
|---|---|
| formaction | 覆盖action |
| formmethod | 覆盖method |
| formenctype | 覆盖enctype |
| formtarget | 覆盖target |
| formnovalidate | 跳过验证 |
提交事件处理
阻止默认提交
text
<form id="myForm" action="/submit">
<input type="text" name="data" required>
<button type="submit">提交</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', (e) => {
e.preventDefault(); // 阻止默认提交
const formData = new FormData(e.target);
// 使用fetch提交
fetch('/api/submit', {
method: 'POST',
body: formData
});
});
</script>
FormData对象
text
const form = document.querySelector('form');
const formData = new FormData(form);
// 获取值
formData.get('username'); // 单值
formData.getAll('tags'); // 多值
// 设置值
formData.set('username', '新值');
formData.append('tags', '额外标签');
// 删除
formData.delete('token');
// 遍历
for (let [key, value] of formData) {
console.log(key, value);
}
要点总结
- GET适合查询,POST适合数据修改和上传
- 文件上传必须使用multipart/form-data
- target控制提交结果窗口
- 按钮可通过form*属性覆盖表单属性
- preventDefault()阻止默认提交实现AJAX提交
- FormData对象方便处理表单数据
📝 发现内容有误?点击此处直接编辑