mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
98 lines
3.0 KiB
Plaintext
98 lines
3.0 KiB
Plaintext
---
|
|
title: Upload files via HTTP using FormData
|
|
sidebarTitle: Upload files via HTTP using FormData
|
|
mode: center
|
|
---
|
|
|
|
To upload files via HTTP with Bun, use the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) API. Let's start with a HTTP server that serves a simple HTML web form.
|
|
|
|
```ts index.ts icon="/icons/typescript.svg"
|
|
const server = Bun.serve({
|
|
port: 4000,
|
|
async fetch(req) {
|
|
const url = new URL(req.url);
|
|
|
|
// return index.html for root path
|
|
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}`);
|
|
```
|
|
|
|
---
|
|
|
|
We can define our HTML form in another file, `index.html`.
|
|
|
|
```html index.html icon="file-code"
|
|
<!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>
|
|
```
|
|
|
|
---
|
|
|
|
At this point, we can run the server and visit [`localhost:4000`](http://localhost:4000) to see our form.
|
|
|
|
```bash
|
|
bun run index.ts
|
|
Listening on http://localhost:4000
|
|
```
|
|
|
|
---
|
|
|
|
Our form will send a `POST` request to the `/action` endpoint with the form data. Let's handle that request in our server.
|
|
|
|
First we use the [`.formData()`](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) method on the incoming `Request` to asynchronously parse its contents to a `FormData` instance. Then we can use the [`.get()`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/get) method to extract the value of the `name` and `profilePicture` fields. Here `name` corresponds to a `string` and `profilePicture` is a `Blob`.
|
|
|
|
Finally, we write the `Blob` to disk using [`Bun.write()`](/runtime/file-io#writing-files-bun-write).
|
|
|
|
{/* prettier-ignore */}
|
|
```ts index.ts icon="/icons/typescript.svg"
|
|
const server = Bun.serve({
|
|
port: 4000,
|
|
async fetch(req) {
|
|
const url = new URL(req.url);
|
|
|
|
// return index.html for root path
|
|
if (url.pathname === "/")
|
|
return new Response(Bun.file("index.html"), {
|
|
headers: {
|
|
"Content-Type": "text/html",
|
|
},
|
|
});
|
|
|
|
// parse formdata at /action // [!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("Must upload a profile picture."); // [!code ++]
|
|
// write profilePicture to disk // [!code ++]
|
|
await Bun.write("profilePicture.png", profilePicture); // [!code ++]
|
|
return new Response("Success"); // [!code ++]
|
|
} // [!code ++]
|
|
|
|
return new Response("Not Found", { status: 404 });
|
|
},
|
|
});
|
|
```
|