R2 对象存储
S3 兼容存储与生命周期。
R2 对象存储
这一课你将能做到
- 创建 R2 Bucket 并在 Worker 中完成对象上传、下载、删除、列表操作
- 生成预签名 URL(Presigned URL)实现前端直传,绕过 Worker 流量
- 配置 R2 生命周期规则(自动删除过期文件)和自定义域名公开访问
为什么要学
用户要上传头像、视频、备份文件。如果全走你的服务器,流量费爆炸,存储费也爆炸。如果直接传 S3,跨区域延迟和出口流量费一样吓人。R2 是 Cloudflare 推出的对象存储,兼容 S3 API,但零出口流量费——无论你从哪里下载,都不收流量钱。
人话:R2 就是一个「不限量 CDN 加速的 S3」。你可以把它当成图片、视频、备份文件的廉价仓库,配合 Worker 做签名、权限控制、自动处理(如图片压缩)。
先建立图像
用户浏览器
│
├── 直接上传 ──> R2 Bucket (通过 Presigned URL)
│
└── 请求 Worker ──> 生成 Presigned URL ──> 返回给用户
│
└── 也可以直接读写 R2 (S3 API)
R2 Bucket
├── 自动同步到边缘节点 (读加速)
├── 生命周期规则 (30天后自动删除)
└── 自定义域名 (cdn.example.com)
跟着做
步骤 1:创建 Bucket
npx wrangler r2 bucket create my-uploads
绑定到 Worker(wrangler.toml):
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-uploads"
步骤 2:Worker 中上传/下载
export interface Env {
MY_BUCKET: R2Bucket;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const key = url.searchParams.get('key');
if (request.method === 'PUT' && key) {
// 上传
const body = await request.arrayBuffer();
await env.MY_BUCKET.put(key, body, {
httpMetadata: { contentType: request.headers.get('content-type') ?? 'application/octet-stream' },
customMetadata: { uploadedBy: 'user123' },
});
return new Response('Uploaded', { status: 201 });
}
if (request.method === 'GET' && key) {
// 下载
const object = await env.MY_BUCKET.get(key);
if (!object) return new Response('Not Found', { status: 404 });
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set('etag', object.httpEtag);
headers.set('Cache-Control', 'public, max-age=31536000');
return new Response(object.body, { headers });
}
if (request.method === 'DELETE' && key) {
await env.MY_BUCKET.delete(key);
return new Response('Deleted');
}
return new Response('Bad Request', { status: 400 });
},
} satisfies ExportedHandler<Env>;