S3 兼容 API 与 SDK 集成
R2 的仪表盘和 wrangler 命令行适合手动管理文件,但真实业务里文件的上传下载通常由代码完成,这就需要用 S3 兼容 API 把 R2 接入到应用代码里。
为什么用 S3 兼容 API
R2 提供了仪表盘和 wrangler 命令行两种管理方式,但它们都不适合写进应用代码。仪表盘是给人操作的图形界面,wrangler 是运维部署工具。程序里要读写 R2 对象,得走标准的 API 调用。
R2 选择了完全兼容 S3 协议。S3 是 AWS 的对象存储服务,它的 API 已经是业界通用标准。好处是任何支持 S3 的 SDK 和工具都能直接用在 R2 上,开发者不用学新接口。
| 接入方式 | 适合场景 | 特点 |
|---|---|---|
| 仪表盘 | 手动测试、小批量维护 | 图形界面,无需配置 |
| wrangler 命令 | 部署脚本、CI/CD | 命令行,适合自动化 |
| S3 兼容 API | 应用代码、后端服务 | 编程语言调用,最灵活 |
获取 API 凭证
用 S3 API 得先拿到三样东西,Access Key ID、Secret Access Key、端点地址。
在 Cloudflare 仪表盘进入 R2 页面,右侧找到”Manage R2 API Tokens”链接点击进入令牌管理页。点击 Create API Token,给令牌起个名字,选择权限(读写都要就勾选 Object Read & Write),再绑定到具体 Bucket 或选所有 Bucket。
创建完成后会显示一次性的凭证信息
| 凭证项 | 说明 | 示例 |
|---|---|---|
| Access Key ID | 访问密钥 ID,可公开标识 | a1b2c3d4e5f6... |
| Secret Access Key | 访问密钥,私密保存 | e5f6g7h8i9j0... |
| Endpoint | S3 端点地址,含账户 ID | https://<accountid>.r2.cloudflarestorage.com |
| Jurisdiction | 管辖区域,默认 EU | eu / fedramp |
Secret Access Key 只在创建时显示一次,必须马上保存,丢了只能重建令牌。
S3 端点格式
R2 的 S3 端点格式固定为
https://<account-id>.r2.cloudflarestorage.com
<account-id> 是 Cloudflare 账户 ID,在仪表盘右侧或令牌创建页能看到。这个端点对所有 Bucket 通用,具体操作哪个 Bucket 由请求参数指定。
如果创建令牌时选了管辖区域(例如数据要存在美国的 fedramp 区域),端点会多一段 jurisdiction
https://<account-id>.<jurisdiction>.r2.cloudflarestorage.com
普通业务保持默认 EU 即可,端点里不带 jurisdiction 段。
AWS SDK JavaScript
R2 推荐用 AWS SDK v3 访问,它模块化设计按需引入,包体积小。先安装
npm install @aws-sdk/client-s3
下面是完整的上传示例
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { readFileSync } from "fs";
const s3 = new S3Client({
region: "auto",
endpoint: "https://你的账户ID.r2.cloudflarestorage.com",
credentials: {
accessKeyId: "你的AccessKeyId",
secretAccessKey: "你的SecretAccessKey",
},
});
const body = readFileSync("./cover.png");
await s3.send(
new PutObjectCommand({
Bucket: "my-assets",
Key: "images/cover.png",
Body: body,
ContentType: "image/png",
})
);
region 填 auto 就行,R2 不像 AWS 那样区分多个区域端点。
下载对象用 GetObjectCommand
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
const res = await s3.send(
new GetObjectCommand({
Bucket: "my-assets",
Key: "images/cover.png",
})
);
// res.Body 是流,转成 Buffer
const chunks = [];
for await (const chunk of res.Body) {
chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);
常用命令对照
| 操作 | 命令类 | 说明 |
|---|---|---|
| 上传 | PutObjectCommand | 写入或覆盖一个对象 |
| 下载 | GetObjectCommand | 读取对象内容 |
| 删除 | DeleteObjectCommand | 删除单个对象 |
| 列表 | ListObjectsCommand | 列出 Bucket 内对象 |
| 头信息 | HeadObjectCommand | 只取元数据不取内容 |
Python boto3
Python 生态用 boto3 最普遍,安装
pip install boto3
配置客户端时把端点指向 R2
import boto3
s3 = boto3.client(
"s3",
endpoint_url="https://你的账户ID.r2.cloudflarestorage.com",
aws_access_key_id="你的AccessKeyId",
aws_secret_access_key="你的SecretAccessKey",
region_name="auto",
)
# 上传文件
s3.upload_file(
Filename="./cover.png",
Bucket="my-assets",
Key="images/cover.png",
ExtraArgs={"ContentType": "image/png"},
)
# 下载文件
s3.download_file("my-assets", "images/cover.png", "./downloaded.png")
boto3 会自动处理 S3 签名版本 4 的计算,开发者不用关心签名细节。
wrangler r2 命令
除了 SDK,wrangler 命令行也内置了 R2 子命令,适合在脚本和 CI 里做批处理。
| 命令 | 作用 |
|---|---|
| wrangler r2 bucket list | 列出所有 Bucket |
| wrangler r2 bucket create |
创建 Bucket |
| wrangler r2 bucket delete |
删除 Bucket |
| wrangler r2 object put | 上传对象 |
| wrangler r2 object get | 下载对象 |
| wrangler r2 object delete | 删除对象 |
上传对象示例
wrangler r2 object put my-assets/images/cover.png --file ./cover.png --content-type image/png
下载对象
wrangler r2 object get my-assets/images/cover.png --file ./downloaded.png
wrangler 命令走 Cloudflare 账号鉴权,不需要单独创建 S3 令牌,用 wrangler login 登录后就能操作。这一点和 S3 API 是两套独立的鉴权体系。
| 对比项 | wrangler r2 | S3 兼容 API |
|---|---|---|
| 鉴权方式 | Cloudflare 账号登录 | Access Key 凭证 |
| 使用场景 | 脚本、CI、运维 | 应用代码、后端服务 |
| 功能范围 | 基础增删查 | 完整 S3 API 能力 |
| 适合人群 | 运维人员、构建脚本 | 后端程序 |
小结
S3 兼容 API 是 R2 接入代码的标准方式,拿到三样凭证后用任何 S3 SDK 都能直接连。下一篇讲怎么把 R2 对象公开访问,让浏览器能直接拉到文件。
上一篇 对象存储基础与 Bucket 管理
下一篇 公开访问与自定义域名