🔥白嫖党狂喜!Cloudflare R2 存储 0 元免费用,国内直连,附保姆级薅羊毛攻略!

零、Cloudflare R2 免费计划核心门槛解析

Cloudflare R2 作为业界领先的对象存储服务,其免费计划为个人用户提供了极具吸引力的资源配额:

1.webp

  • 存储容量:每月 10GB 标准存储(Standard Storage)
  • 操作配额:100 万次写入操作 + 1000 万次读取操作
  • 数据流出:包含基础流量额度(超出需按流量计费)

关键注意事项

  • 首次使用验证:需绑定信用卡或 PayPal 账号(仅用于身份验证,未超配额不产生费用)

  • 计费边界:存储容量按实际占用小时计算,操作次数精确到每千次

  • 官方定价文档详细计费规则查阅

一、Cloudflare R2 基础使用流程

1. 注册与服务开通详解

账号注册步骤:

  1. 访问 Cloudflare 官网 点击 "Sign Up"
  2. 在控制台左侧菜单找到 "R2 Storage"

服务激活要点:

  • 地域选择建议:初次使用推荐亚太区域,网络延迟较低
  • 存储类默认选择:Standard Storage(免费计划仅支持该类型)

2. 存储桶(Bucket)创建全流程

核心配置项说明:

配置项推荐设置说明
存储桶名称全局唯一小写字母组合例:my-photo-bucket-2025,后续可作为自定义域名前缀
区域选择离用户最近的 Cloudflare 节点自动 即可
存储类设置保持 Standard 不变

2.webp

公共访问配置实操:

  1. 进入存储桶详情页,点击 "设置" 标签

3.webp 2. 开启 "公共开发URL" 开关 3. 上传测试文件后,在文件详情页获取形如https://<bucket>.r2.cloudflarestorage.com/<path>的 URL

4.webp

4. 自定义域名绑定高级设置

配置优势:

  • 统一资源访问域名(如https://img.example.com
  • 利用 Cloudflare CDN 节点加速全球访问
  • 支持 HTTPS 免费证书自动部署

前提条件

域名需在cloudfare托管(修改原域名购买网站的dns解析服务器)

操作步骤

  1. 在存储桶设置中选择 "自定义域名"
  2. 输入已托管在 Cloudflare 的域名(如img.example.com

5.webp 4. 系统自动生成 CNAME 记录,确认 DNS 解析生效

6.webp

二、API令牌的获取

7.webp

8.webp

注意:该页面的密钥只展示一次,关闭后无法再次查看

三、桌面端工具 PicGo

1. PicGo 安装与环境配置

稳定版安装包获取:

关键插件安装:

  1. 打开 PicGo 设置中的 "插件设置",搜索s3并安装picgo-plugin-s3插件

9.webp

2.重启 PicGo 使插件生效,根据提示填写

10.webp

2. R2 存储配置参数详解

配置表单填写指南:

字段名称取值示例数据来源说明
存储区域auto保持默认即可,自动适配 Cloudflare 区域
存储桶名称my-photo-bucket-2025填写已创建的 R2 存储桶名称
访问密钥 IDABCDEFGHIJKLMNOPQRSTUVW从 Cloudflare 控制台 API 令牌页面获取
密钥访问密钥1234567890abcdefghijklmnopqrstuvw同上,注意该值仅显示一次需妥善保存
endpointhttps:// <accountID>.r2.cloudflarestorage.com格式固定,accountID 可在存储桶概览页获取
CDN 域名img.example.com填写已绑定的自定义域名

3. 高效上传操作技巧

11.webp

支持的上传方式:

  • 拖拽上传:直接拖放图片到 PicGo 窗口
  • 剪贴板上传:截图后按Ctrl+Shift+P快捷上传
  • 批量上传:选择多个文件一次性导入
  • 插件联动:与 Markdown 编辑器集成,自动替换本地图片链接

三、Spring Boot 后端集成完整方案

1. 依赖管理与版本说明

Maven 依赖配置:

xml
复制代码
<dependencies> <!-- AWS SDK for S3 (兼容Cloudflare R2) --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <version>2.29.52</version> </dependency> <!-- EC2依赖用于区域自动识别 --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>ec2</artifactId> <version>2.29.52</version> </dependency> <!-- HTTP客户端用于底层请求 --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> </dependencies>

版本选择注意事项:

  • 2.30.0 + 版本需额外配置签名算法

12.webp

2. 配置文件与常量管理

application.yml 完整配置:

yml
复制代码
cloud: aws: s3: endpoint: https://abc123.r2.cloudflarestorage.com # 替换为实际accountID bucket-name: my-spring-boot-bucket # 替换为实际存储桶名 cdn-domain: img.example.com # 替换为自定义域名 region: auto # 自动识别区域 credentials: access-key: YOUR_ACCESS_KEY # 替换为API访问密钥 secret-key: YOUR_SECRET_KEY # 替换为API秘密密钥

3. 核心代码实现

config代码

java
复制代码
@Component public class R2FileUtils implements InitializingBean { public static String END_POINT; public static String REGION; public static String BUCKET_NAME; public static String CDN_DOMAIN; public static String ACCESS_KEY; public static String SECRET_KEY; @Value("${cloud.aws.s3.endpoint}") private String endpoint; @Value("${cloud.aws.s3.region}") private String region; @Value("${cloud.aws.s3.bucket-name}") private String bucketName; @Value("${cloud.aws.s3.cdn-domain}") private String cdnDomain; @Value("${cloud.aws.s3.credentials.access-key}") private String accessKey; @Value("${cloud.aws.s3.credentials.secret-key}") private String secretKey; @Override public void afterPropertiesSet() throws Exception { END_POINT = this.endpoint; REGION = this.region; BUCKET_NAME = this.bucketName; CDN_DOMAIN = this.cdnDomain; ACCESS_KEY = this.accessKey; SECRET_KEY = this.secretKey; } }

controller代码

java
复制代码
@RestController @RequestMapping("/api/file") @Api(tags = "文件上传接口") public class FileUploadController { @Resource private FileUploadService fileUploadService; @PostMapping("/r2/upload") @ApiOperation("Cloudflare R2文件上传") @ApiImplicitParam(name = "file", value = "上传文件", required = true, dataType = "MultipartFile") public CommonResult<String> uploadToR2(@RequestPart("file") MultipartFile file) { // 前置校验 if (file.isEmpty()) { return CommonResult.error(ErrorCode.FILE_EMPTY); } // 调用服务层 String url = fileUploadService.uploadToR2(file); return CommonResult.success(url, "上传成功"); } }

serviceImpl核心代码

java
复制代码
@Service public class FileUploadServiceImpl implements FileUploadService { @Override public String uploadToR2(MultipartFile file) { try (InputStream inputStream = file.getInputStream()) { // 构建S3客户端 S3Client s3Client = S3Client.builder() .endpointOverride(URI.create(R2Config.END_POINT)) .credentialsProvider(() -> AwsBasicCredentials.create( R2Config.ACCESS_KEY, R2Config.SECRET_KEY)) .region(Region.of(R2Config.REGION)) .build(); // 生成唯一文件名(含日期路径) String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")); String originalFilename = file.getOriginalFilename(); String fileExt = originalFilename.substring(originalFilename.lastIndexOf(".")); String objectKey = datePath + "/" + UUID.randomUUID() + fileExt; // 构建上传请求 PutObjectRequest putRequest = PutObjectRequest.builder() .bucket(R2Config.BUCKET_NAME) .key(objectKey) .contentType(file.getContentType()) .build(); // 执行上传 s3Client.putObject(putRequest, RequestBody.fromInputStream(inputStream, file.getSize())); // 生成可访问URL(含CDN域名) return R2Config.CDN_DOMAIN + "/" + objectKey; } catch (IOException | S3Exception e) { log.error("R2文件上传失败: {}", e.getMessage(), e); throw new FileUploadException("文件上传失败,请稍后再试"); } } }

接口测试

13.webp

除此之外还可以限制文件大小,格式,设置定期删除等功能,示例中不再赘述。

五、参考资源

  1. 官方核心文档

  2. 社区最佳实践

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
望舒
作者分享
Docker上云踩坑实录
4
友友们,今天计划在服务器上使用docker-compose部署springboot项目。但是遇到了redis连接报错问题。 已经排查了1.docker-compose.env.yml启动在docker-compose.service.yml之前 2.application.yml中关于redis的host,port以及password都是正确的 3.通过docker ps -a发现所有服务状态都是running 4.所有服务都在一个网络当中 现在不知道下一步应该怎么调试了.......
5
Ubuntu22安装docker(含镜像加速配置)
5
兄弟们,求捞!!我是24届专升本毕业生,因为当年春招时海投简历初筛失败,只收到几个公司的面试机会。所以决定考研,但是大部分时间都在摇摆内耗,导致这次复习失败了(感觉很可惜,今年的题目相比去年要简单得多,很多题目都是话到嘴边说不出的感觉....)。但是毕竟已经脱产半年,我怕继续全职备考心态会爆炸。 所以,这几天我准备把简历整理一下,请兄弟们指导一下~ 🤣 比较拿得出手的是: 1.我的一个全栈项目是编程营地(https://coderealm.top)内容还是比较丰富的,刚刚把前端部署上,后端还在犹豫买什么配置的服务器....coming soon 2.英语六级,校级优秀毕业生 3.第六届字节青训营优秀营员 求职的方向是全栈,主要有vue和java的项目经历,能够独立在服务器部署项目。 综上所述,我想在简历、面试经验,工作城市和机会推荐,以及相关企业招聘的消息等方面获得帮助,谢谢啦~
6
唉,感觉自己太失败了。做什么事情都是三分钟热度,马上就考研了,总是逃避。 做题很痛苦,听课很快乐,所以逃避做题。 学习很痛苦,看着自己的cv的代码实现的效果很开心,所以逃避学习,追寻所谓的虚假的成就感。 3月份放弃自己不喜欢的offer,当时暗暗努力一定要考到更高的平台和更多优秀的人做有挑战的事情。其实这半年的时间大部分都荒废了。 现在临近考试很慌,脱产备考压力很大,空窗期怎么解释,要不要继续java.........脑袋里的想法太多了,感觉自己看不到未来。但没有现在的人何谈未来呢。唉,明明知道自己想得太多做的太少,明明知道自己看似知道的太多,其实是纸上谈兵。但是为什么没做到呢。 😭
4
下载 APP