表单数据
FormData 类用于构造表单数据(multipart/form-data),以便在网络请求中上传文本字段或文件数据。
它的行为与浏览器中的 Fetch API FormData 基本一致,但在 Scripting app 中进行了扩展以支持 Data 类型(原生二进制对象),从而更方便地上传文件或图片。
你可以将 FormData 对象直接作为 fetch() 请求的 body 参数使用。系统会自动生成带有正确边界的 multipart/form-data 请求体。
定义
1class FormData {
2 append(name: string, value: string): void
3 append(name: string, value: Data, mimeType: string, filename?: string): void
4 get(name: string): string | Data | null
5 getAll(name: string): any[]
6 has(name: string): boolean
7 delete(name: string): void
8 set(name: string, value: string): void
9 set(name: string, value: Data, filename?: string): void
10 forEach(callback: (value: any, name: string, parent: FormData) => void): void
11 entries(): [string, any][]
12 toJson(): Record<string, any>
13}
主要用途
- 构造带文本与文件混合的表单请求
- 用于文件上传接口(如图片、音频、文档等)
- 代替 JSON 结构上传二进制文件或表单信息
方法说明
append(name: string, value: string): void
append(name: string, value: Data, mimeType: string, filename?: string): void
向表单中添加一个字段。
可以用于添加文本字段或文件数据。
参数说明
| 参数 |
类型 |
说明 |
| name |
string |
字段名称。 |
| value |
string |
Data |
| mimeType |
string |
文件的 MIME 类型(如 "image/png")。仅在传入 Data 时需要。 |
| filename |
string(可选) |
文件名,仅在上传文件时使用。 |
示例
1const form = new FormData()
2form.append("username", "Tom")
3form.append("file", Data.fromFile("/path/to/image.png"), "image/png", "avatar.png")
set(name: string, value: string): void
set(name: string, value: Data, filename?: string): void
设置一个字段的值。
若该字段已存在,则会被覆盖。
与 append() 的区别是:set() 仅保留一个值,而 append() 可重复添加同名字段。
示例
1const form = new FormData()
2form.set("message", "Hello world")
3form.set("file", Data.fromFile("/path/to/file.txt"), "text/plain", "note.txt")
get(name: string): string | Data | null
获取指定字段的值。
如果字段不存在,则返回 null。
示例
1const form = new FormData()
2form.append("title", "My Post")
3console.log(form.get("title")) // 输出: "My Post"
getAll(name: string): any[]
获取同名字段的所有值(如果使用了多次 append())。
示例
1const form = new FormData()
2form.append("tag", "swift")
3form.append("tag", "ios")
4form.append("tag", "scripting")
5
6console.log(form.getAll("tag")) // ["swift", "ios", "scripting"]
has(name: string): boolean
检查表单中是否存在指定名称的字段。
示例
1const form = new FormData()
2form.append("username", "Tom")
3
4console.log(form.has("username")) // true
5console.log(form.has("password")) // false
delete(name: string): void
删除指定名称的字段及其所有值。
示例
1const form = new FormData()
2form.append("title", "Hello")
3form.append("file", Data.fromFile("/path/to/file.txt"), "text/plain")
4
5form.delete("file")
forEach(callback: (value: any, name: string, parent: FormData) => void): void
遍历所有表单字段,执行回调函数。
示例
1const form = new FormData()
2form.append("user", "Tom")
3form.append("age", "25")
4
5form.forEach((value, name) => {
6 console.log(`${name}: ${value}`)
7})
entries(): [string, any][]
返回一个由 [name, value] 组成的键值对数组。
示例
1const form = new FormData()
2form.append("username", "Tom")
3form.append("age", "25")
4console.log(form.entries())
5// [["username", "Tom"], ["age", "25"]]
toJson(): Record<string, any>
将表单数据转换为普通的 JavaScript 对象,用于调试或日志输出。
⚠️ 注意:如果表单中包含文件(Data 类型),此方法不会输出二进制内容,而是显示为占位符信息。
示例
1const form = new FormData()
2form.append("name", "Tom")
3form.append("photo", Data.fromFile("/path/to/avatar.png"), "image/png", "avatar.png")
4
5console.log(form.toJson())
6// { name: "Tom", photo: "[Data: image/png]" }
使用示例
示例 1:上传文件
1const form = new FormData()
2form.append("file", Data.fromFile("/path/to/image.png"), "image/png", "avatar.png")
3form.append("userId", "1234")
4
5const response = await fetch("https://api.example.com/upload", {
6 method: "POST",
7 body: form,
8})
9
10console.log(await response.json())
示例 2:同时上传多个文件
1const form = new FormData()
2form.append("files", Data.fromFile("/path/to/photo1.jpg"), "image/jpeg", "photo1.jpg")
3form.append("files", Data.fromFile("/path/to/photo2.jpg"), "image/jpeg", "photo2.jpg")
4
5await fetch("https://api.example.com/multi-upload", {
6 method: "POST",
7 body: form,
8})
示例 3:构造包含文本与文件的复合请求
1const form = new FormData()
2form.append("title", "Travel Memories")
3form.append("description", "A collection of my travel photos.")
4form.append("cover", Data.fromFile("/path/to/cover.png"), "image/png", "cover.png")
5
6const response = await fetch("https://example.com/uploadPost", {
7 method: "POST",
8 body: form,
9})
10
11console.log(await response.text())
示例 4:遍历并调试表单内容
1const form = new FormData()
2form.append("name", "Alice")
3form.append("file", Data.fromFile("/path/to/file.txt"), "text/plain", "file.txt")
4
5form.forEach((value, name) => {
6 console.log(`${name}:`, value instanceof Data ? "Binary Data" : value)
7})
与其他类的关系
| 类名 |
说明 |
fetch() |
可直接使用 FormData 实例作为请求体。系统会自动设置请求头为 multipart/form-data。 |
Data |
用于表示文件或图片等二进制内容,作为 FormData 字段值传入。 |
Request |
可通过 RequestInit.body 设置 FormData 实例。 |
Response |
可使用 response.formData() 将响应解析为 FormData。 |
注意事项
- 自动设置 Content-Type:使用
FormData 时,fetch() 会自动设置正确的 Content-Type(带边界)。不要手动覆盖。
- 同名字段:支持使用
append() 为同一字段名添加多个值。
- 文件上传:上传文件时需传入 MIME 类型,否则默认可能被识别为
application/octet-stream。
- JSON 转换限制:
toJson() 仅用于调试显示,不适合用于真实数据传输。
小结
FormData 是 Scripting 网络请求体系中用于构造 multipart/form-data 请求的核心类,具备以下特性:
- 支持文本与文件混合上传
- 与
fetch() 无缝集成
- 支持
Data 类型文件传递
- 提供便利的
forEach()、entries()、toJson() 等辅助方法
- 完全兼容 Web 标准的 FormData 行为