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() メソッドを使用して、name と profilePicture フィールドの値を抽出します。ここで name は string に対応し、profilePicture は Blob です。
最後に、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 });
},
});