runlot

put, get, list

ファイルをアップロード、ダウンロードし、一覧を取得する方法を説明します。

アップロード

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 には、ResponseRequest のボディとして使える値を渡せます。FileBlobArrayBufferReadableStream、文字列に対応しています。

contentType を指定しない場合は既定値を使用します。ブラウザにファイルを正しく扱わせたい場合は、明示的に指定してください。

ダウンロード

const obj = await env.storage.get(key);
if (!obj) return new Response("ファイルが見つかりません", { status: 404 });

return new Response(obj.body, {
  headers: {
    "content-type": obj.contentType,
    "content-length": String(obj.size),
    etag: obj.etag,
  },
});

body はストリームです。ファイル全体をメモリに読み込まずにレスポンスへ渡せます。

メタデータだけが必要な場合は head を使用してください。

const meta = await env.storage.head(key);
if (meta && meta.etag === request.headers.get("if-none-match")) {
  return new Response(null, { status: 304 });
}

削除

await env.storage.delete(key);

一覧取得

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 !== "");

cursor が空文字列であれば最後のページです。limit の既定値は 100 件、最大値は 1,000 件です。

prefix はディレクトリではなく文字列の接頭辞です。たとえば covers/ を指定すると、この文字列で始まるすべてのキーを返します。

大きなファイルはブラウザから直接アップロードしてください

ワーカー経由でアップロードすると、リクエストの処理時間とメモリを消費します。大きなファイルは 署名付き URL を使って、ブラウザから直接アップロードするように構成してください。

このページの目次