Cloudflare R2 使用指南:零成本管理博客媒体文件
前言
我的需求
写博客时免不了要插入图片、PDF、视频等媒体文件。以前我采用MinIO 本地管理的方式,在本机搭建一个 MinIO 服务存储文件,再手动同步到 GitHub 仓库的分支上。
这种方式有几个痛点:
- 本地依赖:MinIO 服务必须跑在本机,换设备或重装系统后要重新搭建
- 手动同步:每次新增文件都要手动拷贝到 GitHub 仓库,容易遗漏
- 访问速度:通过 GitHub 访问媒体文件,国内加载速度不理想
- 流量限制:GitHub 仓库的流量和存储都有隐性限制
所以决定迁移到 Cloudflare R2——一个兼容 S3 协议的对象存储服务,提供慷慨的免费额度,而且国内访问速度快。
为什么选择 Cloudflare R2?
| 特性 | MinIO(本地) | GitHub 仓库 | Cloudflare R2 |
|---|---|---|---|
| 部署 | 需自建服务 | 无需部署 | 无需部署 |
| 同步 | 手动 | 手动 | 自动(API) |
| 国内速度 | 快(本地) | 慢 | 快(亚太节点) |
| 免费额度 | 无(自费电费) | 有限 | 10GB 存储 + 每月 1000 万次请求 |
| S3 兼容 | ✅ | ❌ | ✅ |
R2 的免费额度对于个人博客来说绰绰有余:
- 存储:10GB(图片为主的博客基本够用)
- 读取请求:每月 1000 万次
- 写入请求:每月 100 万次
- 出站流量:免费(这是 R2 最大的优势!)
R2 最大的卖点是零出站流量费,不像 AWS S3 那样收昂贵的流量费。对于博客图床来说,几乎零成本。
一、进入 Cloudflare 后台
打开 Cloudflare Dashboard,登录你的账号。
如果你还没有 Cloudflare 账号,可以用邮箱注册一个,免费账号即可使用 R2 服务。
二、添加支付方式
R2 虽然提供免费额度,但 Cloudflare 要求必须绑定支付方式才能激活服务(免费额度内不会扣费)。
操作步骤
- 在页面右上角个人头像下拉菜单中,点击 Billing(账单)
- 进入账单页面后,点击 Add Payment Method(添加付款方式)

- 填写银行卡信息
注意事项
- 银行卡类型:支持银联(UnionPay) 的卡都可以,卡面有银联标志即可,也支持 Visa、MasterCard 等其他类型
- 安全码:印在信用卡/借记卡签名条末端的 3 位数字(CVV 码),不是银行卡号末尾 3 位,注意区分
- 手机验证:Cloudflare 会向银行卡绑定的手机号发送短信验证码,输入验证码即可完成激活
- 费用说明:只是绑定,不会扣费。只有在超出免费额度后才会按量计费
三、激活 R2 服务
绑定支付方式后,就可以激活 R2 了:
- 在左侧导航栏找到 Build → Storage & Databases → R2 Object Storage

- 点击 "Add R2 Subscription to my account"(把 R2 订阅添加到我的账户里)
- 选择刚才添加的银行卡,确认激活即可
激活成功后,你就进入了 R2 的管理页面,可以开始创建存储桶了。
四、创建存储桶(Bucket)
新建桶
点击 Create Bucket,填入以下信息:
| 配置项 | 说明 |
|---|---|
| Bucket Name | 桶名称,全局唯一。建议用有意义的名称,如 blog-media、myblog-images |
| Location | 选择亚太地区(Asia Pacific),这样国内访问速度更快 |

添加自定义域名
桶创建完成后,进入桶的 Settings(设置)页面:
- 找到 Custom Domains(自定义域名)设置
- 点击 Connect Domain,输入你的子域名
域名要求:
- 必须是已经在 Cloudflare 管理的域名的子域名
- 例如我的域名是
lxpavilion.top,我可以使用static.lxpavilion.top作为 R2 的访问域名

添加后 Cloudflare 会自动为这个子域名配置 DNS 记录和 SSL 证书,无需手动操作。
配置 CORS 策略
如果你的博客前端页面从另一个域名请求 R2 上的资源,浏览器会因为 CORS 策略而阻止跨域请求。这时需要在 R2 中配置 CORS 规则。
在桶的 Settings → CORS Policy 中添加规则,例如:
[
{
"AllowedOrigins": ["https://你的博客域名.com"],
"AllowedMethods": ["GET"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]
AllowedOrigins:允许访问的域名,填你的博客地址;如果需要所有域名都能访问,可以用*AllowedMethods:允许的 HTTP 方法,图片展示只需要GETMaxAgeSeconds:预检请求的缓存时间
如果只通过后端程序直接上传下载、不涉及浏览器前端跨域请求,可以跳过这一步。
五、创建 API 密钥
要用代码或工具操作 R2(上传、删除、管理等),需要创建 API 密钥。
- 在 R2 Object Storage 页面右下角,点击 Manage R2 API Tokens

- 点击 Create API Token
- 选择权限:
| 权限 | 说明 |
|---|---|
| Admin Read & Write | 读写权限,适合日常使用 |
| Read Only | 只读,适合前端访问 |
| Object Read & Write | 仅操作文件级别 |
我选择的是 Admin Read & Write,方便管理所有桶。
- 创建后会生成 Access Key ID 和 Secret Access Key,务必复制保存好(关闭页面后密钥不再显示)
如果需要获取你的 Account ID,它也在 R2 Object Storage 页面的右下角,或者在仪表盘 URL 中可以找到。
六、手动上传文件并测试
手动上传
进入桶的页面,点击 Upload 选择文件上传。支持拖拽上传,也可以点击选择文件。

测试访问
上传成功后,使用自定义域名访问测试:
https://static.lxpavilion.top/4.png
访问成功说明配置正确:

七、代码测试文件上传(Python 示例)
R2 兼容 S3 API,所以可以使用任何 S3 兼容的 SDK 进行操作。以下是 Python 的 boto3 示例。
安装依赖
pip install boto3
获取关键信息
- Account ID:在 R2 Object Storage 页面右下角查看
- Access Key ID / Secret Access Key:上一步创建的 API 密钥
- Endpoint URL:格式为
https://<你的Account ID>.r2.cloudflarestorage.com
上传文件
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",
)
bucket_name = "你的桶名称"
local_file_path = "D:/Source/windows/Downloads/logo.png"
object_key = "images/logo.png" # 文件在桶中的路径(可包含目录)
s3.upload_file(local_file_path, bucket_name, object_key)
print("✅ 上传成功!")
print(f"访问地址:https://static.lxpavilion.top/{object_key}")
列出所有文件
response = s3.list_objects_v2(Bucket=bucket_name)
for obj in response.get("Contents", []):
print(f" - {obj['Key']} ({obj['Size']} bytes)")
删除文件
s3.delete_object(Bucket=bucket_name, Key=object_key)
print(f"✅ 已删除:{object_key}")
生成预签名 URL(临时访问)
如果你需要生成一个有时效性的临时访问链接(例如私有文件的分享):
url = s3.generate_presigned_url(
"get_object",
Params={"Bucket": bucket_name, "Key": object_key},
ExpiresIn=3600, # 1 小时后过期
)
print(f"临时访问链接:{url}")
更多 API 操作
官方 API 文档参考:Cloudflare R2 S3 API
八、集成到博客流程
有了 R2 后,我的博客媒体文件管理流程变成:
截图/下载文件
↓
Python 脚本上传到 R2(自动重命名、分类)
↓
获得公开访问链接
↓
粘贴到博客 Markdown 中
↓
博客文章推送到 GitHub Pages
相比之下,以前的 MinIO + GitHub 流程:
截图/下载文件
↓
存到本地 MinIO
↓
手动拷贝到 GitHub 仓库
↓
提交 PR / 推送
↓
等待 GitHub Actions 构建
↓
获得访问链接
↓
粘贴到博客 Markdown
R2 的方式省去了中间手动同步的步骤,流程更短、更自动化。
结语
通过本教程,你已经完成了:
- ✅ Cloudflare 账号的支付方式绑定
- ✅ R2 服务的激活与存储桶创建
- ✅ 自定义域名与 CORS 策略配置
- ✅ API 密钥的创建与权限管理
- ✅ Python SDK 的上传、查询、删除操作
- ✅ 博客媒体文件管理流程的优化
Cloudflare R2 + 自定义域名 + Python 脚本 的组合,几乎零成本解决了个人博客的图床问题。相比 MinIO 本地管理和 GitHub 同步,R2 方案更轻量、更自动化、国内访问速度也更好。
如果你之前也是用 MinIO 或 GitHub 管理媒体文件,强烈建议试试迁移到 R2 💪

浙公网安备 33010602011771号