表单数据

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() 仅用于调试显示,不适合用于真实数据传输。

小结

FormDataScripting 网络请求体系中用于构造 multipart/form-data 请求的核心类,具备以下特性:

  • 支持文本与文件混合上传
  • fetch() 无缝集成
  • 支持 Data 类型文件传递
  • 提供便利的 forEach()entries()toJson() 等辅助方法
  • 完全兼容 Web 标准的 FormData 行为