put, get, list
How to upload, download, and list files.
Upload
app.post("/upload", async (c) => {
const form = await c.req.formData();
const file = form.get("file") as File;
const obj = await c.env.storage.put(`covers/${file.name}`, file, {
contentType: file.type,
});
return Response.json({ key: obj.key, size: obj.size, etag: obj.etag });
});body accepts anything you could use as a Response or Request body: File, Blob, ArrayBuffer, ReadableStream, and strings.
If you don't set contentType, a default is used. Set it explicitly when the browser needs to handle the file correctly.
Download
const obj = await env.storage.get(key);
if (!obj) return new Response("File not found", { status: 404 });
return new Response(obj.body, {
headers: {
"content-type": obj.contentType,
"content-length": String(obj.size),
etag: obj.etag,
},
});body is a stream, so you can pass it straight to the response without loading the whole file into memory.
If you only need the metadata, use head.
const meta = await env.storage.head(key);
if (meta && meta.etag === request.headers.get("if-none-match")) {
return new Response(null, { status: 304 });
}Delete
await env.storage.delete(key);List
let cursor = "";
do {
const page = await env.storage.list({ prefix: "covers/", cursor, limit: 100 });
for (const obj of page.objects) {
console.log(obj.key, obj.size);
}
cursor = page.cursor;
} while (cursor !== "");An empty cursor means you have reached the last page. limit defaults to 100 and can be at most 1,000.
prefix is a string prefix, not a directory. Passing covers/, for example, returns every key that starts with that string.
Let the browser upload large files directly
Uploading through the worker consumes request time and memory. For large files, use a signed URL so the browser uploads directly.