Cloudflare R2 是什么?从零开始部署、计费与访问配置
简答:Cloudflare R2 是一种兼容 S3 API 的对象存储,主要价值是直接从 R2 向互联网传输数据不收取出口流量费。新手最快的验证路径是:创建 R2 订阅和存储桶,使用 Wrangler 或 S3 API 上传一个小文件,再根据用途选择 r2.dev、自定义域名、Worker 或签名 URL。本文为技术资料整理,非 Cloudflare 官方页面;价格和控制台菜单以 2026-11-01 看到的官方页面为准。
定义:Cloudflare R2 是构建在 Cloudflare 网络上的 S3 兼容对象存储,用于保存和读取图片、视频、备份、静态资源及应用生成的非结构化数据。
结论速查:Cloudflare R2 适不适合你
如果你的主要成本来自对象存储容量、读取请求或从存储服务向用户分发文件,R2 值得优先评估;如果你需要复杂的关系查询、虚拟机、文件系统挂载或完整数据库能力,R2 不能单独替代这些服务。
| 需求 | 推荐方式 | 原因与注意事项 |
|---|---|---|
| 上传、下载少量文件 | 控制台 | 无需先写代码,适合初次验证和人工管理。 |
| 已有 S3 程序或 SDK | S3 兼容 API | 通常只需替换 endpoint、凭证和区域配置;仍要核对具体 SDK 的兼容性。 |
| 前端或边缘接口读写文件 | Workers API | 把 R2 bucket 绑定到 Worker,通过绑定对象读写文件,适合 API、鉴权和文件处理。 |
| 本地批量上传与脚本操作 | Wrangler CLI 或 S3 工具 | 适合自动化;凭证必须限制到指定 bucket,并避免写入代码仓库。 |
| 公开图片、安装包或下载文件 | 自定义域名 | 可配合缓存、访问控制和安全策略;r2.dev 仅适合开发或非生产流量。 |
| 私有文件、临时下载 | 私有 bucket + 签名 URL | 不要把 Access Key 放进浏览器;使用服务端生成短期访问地址。 |
官方文档将 R2 定义为 S3 兼容对象存储,并说明其直接出口到互联网不收取数据传输费用;R2 还提供 Workers Binding、S3 API 和 REST API 等访问方式。可查看 R2 官方概览 与 R2 工作原理。
先试这一步:如果只是判断能否正常使用,先创建一个测试 bucket,上传一个文本文件,再用浏览器或 API 读回。上传成功、对象列表能看到文件、下载内容一致,才说明账户、凭证、endpoint 和网络链路基本正常。
费用怎么算:免费额度、Standard 与 Infrequent Access
截至 2026-11-01,官方价格页列出 Standard storage 为 0.015 美元/GB-month,Infrequent Access storage 为 0.01 美元/GB-month。Standard 的 Class A 操作为 4.50 美元/百万请求,Class B 操作为 0.36 美元/百万请求;Infrequent Access 分别为 9.00 美元和 0.90 美元/百万请求,并另外收取 0.01 美元/GB 的数据检索费用。两种存储类型的直接互联网出口均标为免费,但连接其他按量计费的服务时,相关服务仍可能产生费用。价格应以R2 官方价格页当前显示为准。
| 项目 | Standard | Infrequent Access |
|---|---|---|
| 存储 | 0.015 美元/GB-month | 0.01 美元/GB-month |
| Class A | 4.50 美元/百万请求 | 9.00 美元/百万请求 |
| Class B | 0.36 美元/百万请求 | 0.90 美元/百万请求 |
| 数据检索 | 无 | 0.01 美元/GB |
| 直接互联网出口 | 免费 | 免费 |
| 官方免费额度 | 10 GB-month、100 万 Class A、1000 万 Class B | 不适用 |
官方价格页说明免费额度只适用于 Standard,不适用于 Infrequent Access;计费还会按单位向上取整,Infrequent Access 的最短存储时长为 30 天。因此,频繁读取、频繁删除或短期缓存类数据不应只看较低的存储单价。
三个可复算的账单例子
- 个人图片项目:平均 20 GB Standard,假设 Class A 和 Class B 请求均未超过免费额度,存储部分约为 20 × 0.015 = 0.30 美元,再扣除 10 GB-month 免费额度后,约为 0.15 美元;实际账单仍取决于当月平均存储和请求量。
- 1 TB 文件库:按 1000 GB-month 估算,Standard 存储部分为 1000 × 0.015 = 15 美元,扣除 10 GB-month 后约为 14.85 美元;请求费用和其他服务费用另算。
- 高频静态资源:官方示例中,10 万个平均 100 KB 的文件每天被读取 1000 万次,月度 Class B 请求可能成为主要费用来源,不能只按存储容量估算。
更稳妥的做法是记录每月平均存储量、PUT/POST/LIST 等写入操作、GET/HEAD 等读取操作、Infrequent Access 的读取量,以及是否经过其他计费服务,再代入公式:月费用 = 存储费 + Class A 请求费 + Class B 请求费 + 检索费 + 其他关联服务费用。
从零开始:账户、存储桶、凭证与第一次上传
- 准备账户和订阅。需要 Cloudflare 账户和 R2 subscription。官方入门页说明,首次使用时进入控制台的 Storage & databases → R2 → Overview,完成订阅流程后按月按用量计费;页面显示包含免费月度用量,可参考R2 入门文档。
- 创建 bucket。可以在控制台选择 Create bucket,填写名称、位置和默认存储类别;也可以在已安装 Node.js 的终端执行:
npx wrangler login,然后执行npx wrangler r2 bucket create my-bucket,用npx wrangler r2 bucket list验证。bucket 名称请使用你自己的名称。 - 选择访问方式。只做人工测试可用控制台;已有 S3 程序使用 S3 API;需要鉴权、改写响应或与前端接口整合时使用 Worker;批量脚本则选择 Wrangler、AWS CLI、rclone 或对应语言 SDK。
- 生成 S3 凭证。在 R2 的 API Tokens 中创建 Account API token 或 User API token,权限优先选择 Object Read & Write,并限制到指定 bucket。创建后只保存一次 Secret Access Key,不要放在浏览器、公开仓库、截图或聊天记录中。官方 S3 入门页给出的 endpoint 格式是:
https://<ACCOUNT_ID>.r2.cloudflarestorage.com。 - 用 Python 验证上传和下载。安装依赖:
pip install boto3。把下面示例中的占位符替换为自己的值:import boto3 s3 = boto3.client('s3', endpoint_url='https://<ACCOUNT_ID>.r2.cloudflarestorage.com', aws_access_key_id='<ACCESS_KEY_ID>', aws_secret_access_key='<SECRET_ACCESS_KEY>', region_name='auto') s3.upload_file('myfile.txt', 'my-bucket', 'myfile.txt') s3.download_file('my-bucket', 'myfile.txt', 'downloaded.txt') print(s3.list_objects_v2(Bucket='my-bucket'))。完整接口说明可参阅R2 S3 入门文档。 - 设定成功标准。上传命令没有鉴权错误;对象列表能看到目标 key;下载后的文件大小和校验值与本地文件一致;在第二台设备或不同网络下重复读取,确认问题不是本地缓存或 DNS。
如果你的应用本身运行在 Worker 中,可以改用 R2 binding。官方示例使用 npm create cloudflare@latest -- r2-worker 创建项目,在 Wrangler 配置中加入 r2_buckets 绑定,再通过 env.MY_BUCKET.put() 和 env.MY_BUCKET.get() 读写对象;本地 wrangler dev 默认使用本地模拟状态,不能把本地成功误认为生产 bucket 已验证。具体步骤见Workers API 入门文档。
公开文件、域名、缓存与 CORS 怎么选
r2.dev:适合临时开发和快速验证。官方文档明确说明,r2.dev 会限流,只应用于开发用途;不要再为 r2.dev 额外创建 CNAME,因为这是不受支持的访问路径。需要缓存、WAF、访问控制或机器人管理时,应使用自定义域名。
自定义域名:域名需要先加入与 bucket 相同账户的 Cloudflare zone,然后进入 bucket → Settings → Custom Domains → Add,确认 DNS 记录并连接。状态从 Initializing 变为 Active 后再测试。自定义域名可以配合 Cloudflare Cache;但默认只缓存部分文件类型,是否缓存全部文件应按缓存规则核对。步骤和限制见R2 公共 bucket 与自定义域名文档。
CORS:浏览器直接从前端域名上传或读取 R2 时,需要在 bucket 配置允许的 Origin、方法和请求头。排查时先看浏览器 Network 面板:如果预检 OPTIONS 没有返回正确的 Access-Control-Allow-Origin 或允许方法,问题通常在 CORS 配置,而不一定是 R2 凭证错误。不要为了省事长期使用任意 Origin,生产环境应填写实际前端域名。配置细节参考R2 CORS 文档。
私有文件:不要把 bucket 设为公开后再试图用前端隐藏地址实现安全控制。对于用户头像原图、合同、备份和内部资料,应保持 bucket 私有,由服务端校验用户权限,再生成短期签名 URL。签名 URL 只应授予必要的 HTTP 方法和有效时间,相关方法见R2 Presigned URLs 文档。
限制、兼容性与生产环境注意事项
| 项目 | 官方页面可核实内容 | 实际影响 |
|---|---|---|
| 对象大小 | 单个对象上限为 5 TiB,但脚注说明实际限制比 5 TiB 少 5 GiB,即 4.995 TiB。 | 大文件应使用 multipart upload,并测试中断、重试和断点续传。 |
| 对象数量与 bucket 存储 | 每个 bucket 的对象数和数据存储标为 unlimited;账户 bucket 默认限制为 100,000,超过部分可能收费。 | 大量租户或批量迁移前要核对账户限制和管理操作频率。 |
| bucket 管理操作 | 每个 bucket 的创建、删除、列举和配置类管理操作为每秒 50 次。 | 批量自动建桶不要并发冲击控制台或 API。 |
| 自定义域名 | 每个 bucket 最多 100 个 custom domains。 | 多品牌、多租户分域名时需提前设计。 |
| S3 兼容性 | R2 提供 S3-compatible API,但不是所有 S3 特性都应默认视为完全一致。 | 迁移前应测试 SDK、签名、分片上传、ACL、生命周期和错误处理。 |
官方限制页还列出对象 key 长度和对象元数据大小等限制,详见R2 平台限制。生产环境不要只做一次上传测试,还应验证:删除保护或备份策略、生命周期规则、CORS、签名 URL 过期、跨网络下载、DNS 解析、缓存命中与回源、异常重试,以及删除对象后应用是否仍保存旧 URL。
R2 不是数据库,也不会自动替你完成备份、版本管理、业务权限和灾难恢复。图片站通常是“R2 + 自定义域名 + 缓存”;私有下载站通常是“R2 私有 bucket + Worker 鉴权 + 签名 URL”;应用上传通常是“前端直传或 Worker 中转 + CORS + multipart upload”。组合方式应由访问模式和安全边界决定,而不是只按存储单价选择。
常见报错与分层排查
AccessDenied 或 403
先核对 Access Key 是否属于正确账户,token 是否包含目标 bucket 的 Object Read 或 Object Write 权限,bucket 名称和对象 key 是否区分大小写。若权限只允许指定 bucket,不要把其他 bucket 的测试结果当作凭证失效。确认后再重新生成最小权限 token。
SignatureDoesNotMatch
重点检查 endpoint、Access Key、Secret Access Key、region 是否按 SDK 要求填写。R2 的官方示例使用 region_name='auto';同时检查本机时间是否明显错误、请求是否被代理或中间件改写。不要把 Secret 直接贴到日志中。官方价格页还说明,因认证失败产生的部分 401 或 403 请求不会按正常操作计费,但其他已经通过认证后发生的失败可能计入对应操作。
浏览器 CORS 失败
使用 Network 面板查看 OPTIONS 预检和实际请求,确认 Origin、方法、Content-Type、自定义请求头都在 bucket CORS 规则中。若 API 工具上传成功而浏览器失败,优先查 CORS;若所有客户端都失败,再查凭证、endpoint 和 DNS。
r2.dev 能打开但自定义域名打不开
先确认自定义域名状态为 Active,再检查 zone 是否在同一账户、DNS 记录是否按控制台生成、域名是否被其他记录占用。不要用 CNAME 指向 r2.dev 代替官方的连接流程。若启用了 WAF 或 Access,还要确认没有同时保留可绕过控制策略的公开 r2.dev 入口。
大文件上传中断
改用 multipart upload,记录 upload ID 和 part 编号,设置超时、重试和失败清理。不要把一次性 PUT 作为所有大文件的生产方案;还要核对客户端、反向代理、Worker 请求体和网络链路的大小限制。
最终决策:哪些场景优先用 R2,哪些场景先谨慎
优先考虑 R2:静态图片和附件、软件包或数据文件下载、播客和媒体素材、应用生成的备份、需要 S3 工具迁移的对象数据,以及出口流量占比高的文件分发场景。
先做小规模验证:高频小对象读取、短期大量写入后删除、对 S3 特性依赖很深的现有系统、需要明确数据位置或合规边界的业务、多个域名和大量租户共用一个账户的架构。
最短闭环是:先用 Standard 创建测试 bucket → 用最小权限凭证上传和下载 → 决定公开域名或私有签名 URL → 配置 CORS 和缓存 → 按真实存储量与请求量估算账单 → 再迁移生产数据。没有完成这条闭环前,不要把“能创建 bucket”当成“生产架构已经可用”。
常见问题
Cloudflare R2 是免费的吗?
不是完全免费。官方当前页面列出 Standard 每月 10 GB-month 存储、100 万 Class A 和 1000 万 Class B 免费额度;超出后按存储和请求计费,Infrequent Access 不适用这组免费额度。直接从 R2 向互联网传输数据标为免费,但其他关联服务可能收费。
R2 和 S3 有什么关系?
R2 提供 S3-compatible API,可以使用许多 S3 SDK、库和工具,通常需要替换 endpoint、凭证和区域配置。但兼容并不等于所有 S3 特性完全相同,迁移前应测试分片上传、签名、权限、生命周期和错误处理。
Cloudflare R2 可以直接当图片 CDN 使用吗?
可以作为图片或静态文件的对象存储来源,但生产环境通常应使用自定义域名并配置缓存。r2.dev 官方定位是开发用途并且会限流,不应作为正式高流量分发入口。
R2 的 r2.dev 和自定义域名怎么选?
临时测试可用 r2.dev;需要缓存、WAF、Access、Bot Management 或稳定的业务域名时选择自定义域名。不要自行创建 CNAME 指向 r2.dev,按 bucket 设置中的 Custom Domains 流程连接。
R2 适合做数据库或网盘吗?
R2 适合保存文件对象,不是关系数据库。它可以作为网盘的文件层,但账号、目录、搜索、配额、权限、分享链接和回收站仍需由应用和数据库实现。
为什么上传成功但浏览器读取失败?
优先检查 bucket 是否公开、域名是否 Active、CORS 是否允许当前 Origin 和请求方法,以及前端是否误用了私有凭证。命令行成功而浏览器失败时,通常先查 CORS;所有客户端都失败时,再查 endpoint、权限和 DNS。