Skip to content

Bun で HTTP 経由でファイルをアップロードするには、FormData API を使用します。シンプルな HTML ウェブフォームを提供する HTTP サーバーから始めましょう。

ts
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
<!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 を訪問すると、フォームが表示されます。

bash
bun run index.ts
Listening on http://localhost:4000

フォームは、フォームデータを添えて /action エンドポイントに POST リクエストを送信します。そのリクエストをサーバーで処理しましょう。

まず、受信した Request.formData() メソッドを使用して、その内容を FormData インスタンスに非同期で解析します。次に、.get() メソッドを使用して、nameprofilePicture フィールドの値を抽出します。ここで namestring に対応し、profilePictureBlob です。

最後に、Bun.write() を使用して Blob をディスクに書き込みます。

ts
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 を解析
    if (url.pathname === "/action") { 
      const formdata = await req.formData(); 
      const name = formdata.get("name"); 
      const profilePicture = formdata.get("profilePicture"); 
      if (!profilePicture) throw new Error("Must upload a profile picture."); 
      // profilePicture をディスクに書き込む
      await Bun.write("profilePicture.png", profilePicture); 
      return new Response("Success"); 
    } 

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

Bun by www.bunjs.com.cn 編集