> ## Documentation Index
> Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 FormData 通过 HTTP 上传文件

要通过 HTTP 使用 Bun 上传文件，请使用 [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) API。我们先从一个提供 HTML 网页表单的 HTTP 服务器开始。

```ts index.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
const server = Bun.serve({
  port: 4000,
  async fetch(req) {
    const url = new URL(req.url);

    // 根路径返回 index.html
    if (url.pathname === "/")
      return new Response(Bun.file("index.html"), {
        headers: {
          "Content-Type": "text/html",
        },
      });

    return new Response("Not Found", { status: 404 });
  },
});

console.log(`Listening on http://localhost:${server.port}`);
```

***

我们可以在另一个文件 `index.html` 中定义我们的 HTML 表单。

```html index.html icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Form</title>
  </head>
  <body>
    <form action="/action" method="post" enctype="multipart/form-data">
      <input type="text" name="name" placeholder="Name" />
      <input type="file" name="profilePicture" />
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>
```

***

此时，我们可以运行服务器并访问 [`localhost:4000`](http://localhost:4000) 来查看我们的表单。

```bash theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run index.ts
Listening on http://localhost:4000
```

***

我们的表单会向 `/action` 端点发送包含表单数据的 `POST` 请求。让我们在服务器端处理该请求。

首先，我们使用传入 `Request` 对象上的 [`.formData()`](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) 方法异步解析其内容为 `FormData` 实例。然后，我们可以使用 [`.get()`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/get) 方法提取 `name` 和 `profilePicture` 字段的值。其中 `name` 是一个 `string`，`profilePicture` 是一个 `Blob`。

最后，我们使用 [`Bun.write()`](/runtime/file-io#writing-files-bun-write) 将 `Blob` 写入磁盘。

```ts index.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
const server = Bun.serve({
  port: 4000,
  async fetch(req) {
    const url = new URL(req.url);

    // 根路径返回 index.html
    if (url.pathname === "/")
      return new Response(Bun.file("index.html"), {
        headers: {
          "Content-Type": "text/html",
        },
      });

    // 在 /action 路径解析 formdata // [!code ++]
    if (url.pathname === "/action") { // [!code ++]
      const formdata = await req.formData(); // [!code ++]
      const name = formdata.get("name"); // [!code ++]
      const profilePicture = formdata.get("profilePicture"); // [!code ++]
      if (!profilePicture) throw new Error("必须上传个人头像。"); // [!code ++]
      // 将 profilePicture 写入磁盘 // [!code ++]
      await Bun.write("profilePicture.png", profilePicture); // [!code ++]
      return new Response("成功"); // [!code ++]
    } // [!code ++]

    return new Response("未找到", { status: 404 });
  },
});
```
