当知道 Cloudflare 大善人 有 R2 的时候,我就想搞,后面发现要绑定卡,搞了一个人人卡,总算是绑定上了,既然绑定上了,那肯定要给他用起来呀,然后我就再 github 上遨游了一会,发现

这个项目,然后我就按照教程部署了一下,发现界面有点不太喜欢,于是我就 CC 启动,给他美化,美化完想着,能不能再加一些功能呢,于是又加了一些功能。
原本也想过用 openList,部署了后想着如果只用 R2 的话还不如就用这个更方便以及定制化会好很多。

核心功能

功能说明
文件管理上传、下载、重命名、移动、删除
文件夹支持创建文件夹、文件夹重命名、文件夹下载(打包 ZIP)
高级搜索支持文件名、类型、扩展名、大小多维度搜索
缩略图预览图片和视频自动生成缩略图
响应式设计完美支持 PC 和移动端
大文件上传支持最大 5GB 文件(分片上传)

现代化 UI

功能说明
主题切换支持亮色 / 暗色模式,跟随系统或手动切换
卡片布局类 Notion 风格的现代化界面
统计面板存储概览、文件统计、类型分布
操作统计R2 A 类 / B 类操作次数统计(需配置)

批量操作

功能说明
多选模式批量选择文件和文件夹
批量下载多文件打包 ZIP 下载
批量删除一键删除多个文件
批量移动批量移动到指定目录

文件分享

功能说明
分享链接生成文件分享链接
时效控制支持 1 小时 / 1 天 / 7 天 / 30 天 / 永久 / 自定义
密码保护可选设置访问密码
下载限制可选限制最大下载次数
wget 命令自动生成 wget 下载命令

权限系统

功能说明
多用户支持支持多管理员账户
目录授权为不同用户分配不同目录权限
只读用户支持只能查看和下载的只读账户
访客模式可配置访客可访问的目录(仅查看)
现代化登录自定义登录界面,非浏览器弹窗


界面预览

主界面 - 亮色主题

主界面 - 暗色主题

文件上传

高级搜索

文件分享

统计面板

登录界面

分享管理

移动端适配


快速部署

前置要求

  • Cloudflare 账户(免费即可)
  • GitHub 账户

部署步骤

第一步:Fork 仓库

点击本仓库右上角的 Fork 按钮,将仓库复制到你的 GitHub 账户。

第二步:创建 R2 存储桶

  1. 登录 Cloudflare 控制台
  2. 左侧菜单选择 R2 对象存储
  3. 点击 创建存储桶
  4. 输入存储桶名称(如 my-drive),选择地区,点击创建
  5. 进入存储桶 → 设置公开访问
  6. 点击 允许访问,复制 公共存储桶 URL(格式如:https://pub-xxx.r2.dev

建议:同时设置 对象生命周期规则,添加 "中止未完成的分段上传(1 天)",避免上传中断产生的垃圾数据。

第三步:创建 Pages 项目

  1. 进入 Cloudflare 控制台 → Workers 和 Pages
  2. 点击 创建Pages连接到 Git
  3. 选择你 Fork 的仓库
  4. 项目名称可自定义(如 my-drive
  5. 框架预设 保持默认(无)
  6. 展开 环境变量(高级),添加以下变量:
变量名称说明
PUBURLhttps://pub-xxx.r2.dev你的公共存储桶 URL
GUESTpublic/访客可访问目录(留空则禁止)
admin:你的密码*管理员账户,* 表示所有目录权限
  1. 点击 保存并部署

第四步:绑定 R2 存储桶

  1. 部署完成后,进入 Pages 项目
  2. 设置函数R2 存储桶绑定
  3. 点击 添加绑定
  4. 变量名称填写:BUCKET
  5. R2 存储桶选择你创建的存储桶
  6. 点击保存

第五步:绑定 KV 命名空间(分享功能需要)

  1. 进入 Cloudflare 控制台 → Workers 和 PagesKV
  2. 点击 创建命名空间,名称填写 ossShares
  3. 回到 Pages 项目 → 设置函数KV 命名空间绑定
  4. 点击 添加绑定
  5. 变量名称填写:ossShares
  6. KV 命名空间选择刚创建的 ossShares
  7. 点击保存

第六步:重新部署

  1. 进入 部署 页面
  2. 找到最新的部署,点击右侧 重试部署
  3. 等待部署完成,访问你的域名即可使用


环境变量配置

配置概览

变量名必需说明示例
PUBURLR2 公共存储桶 URLhttps://pub-xxx.r2.dev
BUCKETR2 存储桶绑定(在函数设置中配置)-
ossSharesKV 命名空间绑定(分享功能需要)-
FILE_BASE_URL前端文件访问 URL(CDN 回源场景)https://cdn.example.com
GUEST访客可访问目录public/
GUEST_UPLOAD_PASSWORD访客上传密码your_password
CF_ACCOUNT_IDCloudflare 账户 ID(操作统计需要)abc123...
CF_API_TOKENAPI Token(操作统计需要)xxx...
R2_BUCKET_NAME指定统计的存储桶名称my-drive

基础配置

PUBURL(必需)

R2 公共存储桶的访问 URL,用于服务端获取文件。

PUBURL = https://pub-xxx.r2.dev

获取方式:进入 R2 存储桶 → 设置 → 公开访问 → 复制公共存储桶 URL

FILE_BASE_URL(可选)

前端文件访问的基础 URL。用于 CDN 回源场景,如果不配置则使用 Pages Function 代理。

FILE_BASE_URL = https://cdn.example.com

用户与权限配置

用户账户配置

用户以 用户名:密码 格式作为变量名,权限配置作为

变量名(用户名:密码)值(权限)说明
admin:123456*管理员,拥有所有权限
user1:password1普通用户,可读写指定目录
viewer:password2readonly, public/只读用户,只能查看和下载

权限值说明

权限值说明
*管理员,拥有所有目录的读写权限
path1/, path2/普通用户,可读写指定目录(多个用逗号分隔)
readonly, path/只读用户,只能查看和下载指定目录

访客配置

变量名说明
GUESTpublic/, shared/访客可访问的目录(仅查看和下载)
GUEST_UPLOAD_PASSWORDyour_password访客上传密码(可选)

注意事项

  • 目录路径不要/ 开头
  • 目录路径建议/ 结尾
  • 访客默认只能查看和下载,不能上传
  • 配置 GUEST_UPLOAD_PASSWORD 后,访客输入正确密码可上传文件
  • 访客看不到统计面板

配置示例

# 管理员账户
admin:MySecurePassword123 = *

# 普通用户 - 可以读写 photos 和 documents 目录
alice:alice123 = photos/, documents/

# 只读用户 - 只能查看 public 目录
bob:bob456 = readonly, public/

# 访客可访问的目录
GUEST = public/, shared/

# 访客上传密码(可选)
GUEST_UPLOAD_PASSWORD = guest_upload_2024

操作统计配置(可选)

如需启用 R2 操作统计(A 类 / B 类操作次数),需添加以下变量:

变量名必需说明
CF_ACCOUNT_IDCloudflare 账户 ID
CF_API_TOKENAPI Token(需 Analytics 读取权限)
R2_BUCKET_NAME指定统计的存储桶名称(不填则统计所有)

获取账户 ID

  1. 登录 Cloudflare 控制台
  2. 右侧边栏可以看到 账户 ID
  3. 复制该 ID

创建 API Token

  1. 进入 API Tokens 页面
  2. 点击 创建令牌
  3. 选择 创建自定义令牌
  4. 配置权限:
    • 账户Account Analytics读取
  5. 账户资源选择你的账户
  6. 点击 继续以显示摘要创建令牌
  7. 复制生成的 Token

操作类型说明

类型包含操作计费
A 类操作PUT、POST、DELETE、ListObjects、上传、复制等较高
B 类操作GET、HEAD、下载、查询等较低

统计周期为最近 30 天,数据缓存 30 分钟。

CDN 回源配置(可选)

如果你想通过第三方 CDN(如 EdgeOne、又拍云等)回源访问文件,可以配置 FILE_BASE_URL

架构示意

用户浏览器
    ↓ 访问
CDN (例如 EdgeOne)
    ↓ 回源
R2 公共存储桶

配置步骤

  1. 配置 CDN 回源到 R2

    • 在 CDN 控制台创建站点(如 cdn.example.com
    • 配置回源地址为 R2 公共 URL(如 https://pub-xxx.r2.dev
  2. 设置环境变量

    FILE_BASE_URL = https://cdn.example.com
    
  3. 工作原理

    • 前端请求文件时会使用 FILE_BASE_URL(如 https://cdn.example.com/file.jpg
    • 用户浏览器直接请求 CDN
    • CDN 回源到 R2 获取文件

不配置时的默认行为

如果不配置 FILE_BASE_URL

  • 前端使用 /raw/file.jpg 相对路径
  • 请求通过 Cloudflare Pages Function 代理到 R2


使用指南

基本操作

上传文件

  • 点击右下角 上传按钮
  • 或直接 拖拽文件 到页面任意位置

创建文件夹

  • 点击上传按钮 → 选择 新建文件夹
  • 或点击工具栏的文件夹图标

文件操作

  • 单击文件:预览 / 下载
  • 右键 / 长按:打开操作菜单(重命名、下载、复制、移动、删除)

批量操作

  1. 点击工具栏的 选择图标 进入选择模式
  2. 点击文件卡片左上角的复选框选择文件
  3. 底部浮动栏显示已选数量和操作按钮
  4. 可进行批量下载、移动、删除

登录与权限

登录

  1. 点击顶部导航栏右侧的 登录按钮
  2. 在弹出的登录对话框中输入用户名和密码
  3. 登录成功后会显示用户头像和用户名

查看权限

  • 登录后点击用户头像,展开下拉菜单
  • 可以看到当前用户的角色(管理员 / 普通用户)
  • 显示可写入的目录列表
  • 管理员拥有所有目录权限

退出登录

  • 点击用户头像 → 点击 退出登录
  • 退出后将以访客身份浏览

主题切换

点击顶部导航栏右侧的 太阳 / 月亮图标 切换亮色 / 暗色主题。

视图切换

工具栏提供两种视图:

  • 网格视图:卡片式布局,适合浏览图片
  • 列表视图:紧凑列表,适合查看详细信息

高级搜索

支持两种搜索方式:

方式一:可视化搜索面板

点击搜索框右侧的 筛选图标 打开高级搜索面板,可以:

  • 选择文件类型(图片、视频、文档、压缩包、程序等)
  • 输入扩展名筛选(如 .pdf.jar
  • 设置文件大小范围

方式二:搜索语法

直接在搜索框输入查询语法:

语法说明示例
type:类型按文件类型筛选type:图片type:视频type:压缩
ext:扩展名.扩展名按扩展名筛选ext:pdf.jarext:mp4,mkv
size>大小大于指定大小size>=1GB
size<大小小于指定大小
size:范围大小范围
关键词文件名包含backup2024

支持的文件类型:

类型关键词
图片图片
视频video视频vid
文档document文档doctext
压缩包archive压缩zip
程序executable程序exe
其他other其他

支持的大小单位: BKBMBGBTB(不区分大小写)

组合查询示例:

文件分享

创建分享

  1. 右键点击文件 → 选择 分享
  2. 设置分享选项:
    • 有效期:1 小时 / 1 天 / 7 天 / 30 天 / 永久 / 自定义分钟
    • 密码保护:可选,设置访问密码
    • 下载限制:可选,限制最大下载次数
  3. 点击 创建分享链接
  4. 复制分享链接或 wget 命令

分享链接格式

类型格式
网页访问https://your-domain.com/s/{shareId}
直接下载https://your-domain.com/s/{shareId}/download
带密码下载https://your-domain.com/s/{shareId}/download?pwd=密码

wget 下载示例

# 无密码
wget --content-disposition "https://your-domain.com/s/abc123/download"

# 有密码
wget --content-disposition "https://your-domain.com/s/abc123/download?pwd=mypassword"

分享管理(管理员功能)

管理员可以查看和管理所有用户创建的分享链接。

打开分享管理

  1. 以管理员身份登录
  2. 点击顶部导航栏的用户头像
  3. 在下拉菜单中点击 分享管理

分享列表信息

字段说明
文件名分享的文件名称
文件大小文件大小
密码状态是否设置了访问密码
创建时间分享创建的时间
过期状态显示剩余时间或已过期
下载次数已下载次数 / 最大下载次数
创建者创建分享的用户

管理操作

  • 复制链接:快速复制分享链接
  • 删除分享:删除该分享(文件本身不会被删除)

过期状态说明

状态颜色说明
永久绿色永久有效的分享
X 天 / 小时后灰色 / 黄色即将过期
已过期红色分享已失效


本地开发

环境要求

  • Node.js 18+
  • pnpm(推荐)或 npm

开发步骤

# 克隆仓库
git clone https://github.com/你的用户名/Cloudflare-R2-oss.git
cd Cloudflare-R2-oss

# 安装依赖
pnpm install

# 启动开发服务器
pnpm dev

开发服务器启动后访问 http://localhost:8788

构建部署

# 构建
pnpm build

# 部署到 Cloudflare Pages
pnpm deploy


项目结构

Cloudflare-R2-oss/
├── assets/                 # 前端资源
│   ├── App.vue            # 主应用组件
│   ├── Header.vue         # 顶部导航栏(含用户菜单、搜索)
│   ├── AdvancedSearchPanel.vue # 高级搜索面板
│   ├── StatsCards.vue     # 统计卡片
│   ├── Breadcrumb.vue     # 面包屑导航
│   ├── Toolbar.vue        # 工具栏
│   ├── FileCard.vue       # 文件卡片
│   ├── BatchBar.vue       # 批量操作栏
│   ├── Dialog.vue         # 对话框基础组件
│   ├── LoginDialog.vue    # 登录对话框
│   ├── ShareDialog.vue    # 分享对话框
│   ├── ShareListDialog.vue # 分享列表对话框
│   ├── InputDialog.vue    # 输入对话框
│   ├── ConfirmDialog.vue  # 确认对话框
│   ├── Toast.vue          # 消息提示组件
│   ├── Menu.vue           # 菜单组件
│   ├── UploadPopup.vue    # 上传弹窗
│   ├── MimeIcon.vue       # 文件图标
│   ├── search.mjs         # 搜索解析引擎
│   ├── main.css           # 全局样式
│   ├── main.mjs           # 工具函数(上传、缩略图等)
│   ├── favicon.svg        # 网站图标
│   └── manifest.json      # PWA 配置
├── functions/              # Cloudflare Pages Functions
│   ├── api/
│   │   ├── auth.ts        # 认证 API
│   │   ├── config.ts      # 配置 API
│   │   ├── stats.ts       # 统计 API
│   │   ├── children/      # 文件列表 API
│   │   ├── share/         # 分享管理 API
│   │   └── write/         # 文件操作 API
│   ├── raw/               # 文件代理
│   └── s/                 # 分享页面
│       └── [id].ts        # 分享详情页
├── utils/                  # 工具函数
│   ├── auth.ts            # 权限验证
│   └── share.ts           # 分享工具
├── docs/                   # 文档资源
│   └── images/            # 截图图片
├── index.html             # 入口页面
├── wrangler.toml          # Wrangler 配置
├── package.json           # 项目配置
└── README.md              # 说明文档


常见问题

部署相关

Q: 上传失败怎么办?

检查以下几点:

  1. 是否已正确绑定 R2 存储桶,变量名必须是 BUCKET
  2. R2 存储桶是否已开启公开访问
  3. PUBURL 环境变量是否配置正确
Q: 为什么看不到操作统计?

操作统计需要配置以下环境变量:

  • CF_ACCOUNT_ID:Cloudflare 账户 ID
  • CF_API_TOKEN:API Token(需 Analytics 读取权限)

请参考 操作统计配置 章节。

Q: 如何自定义域名?

在 Pages 项目设置中添加自定义域名,Cloudflare 会自动配置 SSL。

Q: 忘记密码怎么办?

在 Pages 环境变量中查看、修改对应用户的密码,修改后重新部署即可。

文件操作相关

Q: 支持多大的文件?

单文件支持最大 5GB(使用分片上传)。

大文件上传建议使用稳定的网络环境,避免上传中断。

Q: R2 控制台显示 "正在进行的多部分上传" 无法删除怎么办?

这些是未完成的分段上传(Multipart Uploads),通常是因为大文件上传中断或失败导致的。它们不是真正的文件对象,所以无法通过常规方式删除。

解决方法:设置生命周期规则(推荐)

  1. 登录 Cloudflare 控制台
  2. 进入 R2 对象存储 → 选择你的存储桶
  3. 点击 设置(Settings) 标签
  4. 找到 对象生命周期规则(Object lifecycle rules)
  5. 添加规则:中止未完成的分段上传,设置为 1 天后自动删除
  6. 保存后等待规则生效,那些未完成的上传会被自动清理
Q: 重命名文件夹后,原文件夹没有被删除?

这通常是因为原文件夹中存在未完成的多部分上传

原因说明:

  • 重命名文件夹时,系统会复制所有文件到新路径,然后删除原文件
  • R2 的 list 操作只返回已完成的对象,不会返回 "正在进行的多部分上传"
  • 所以那些未完成的上传不会被迁移,残留在原路径下
  • 因为有这些残留的 "对象",R2 会继续显示原文件夹

解决方法: 参考上一个问题,设置生命周期规则清理未完成的分段上传,清理后原文件夹会自动消失。

Q: 为什么重命名文件夹这么慢?能不能直接改名?

这是对象存储(S3/R2)的固有限制,无法绕过。

技术原因:

  • R2(以及 AWS S3)中没有真正的 "文件夹" 概念
  • 文件夹只是通过对象 key 的前缀来模拟的
  • 例如 docs/file.pdf 就是一个完整的 key,不是 "docs 文件夹里的 file.pdf"
  • 要把它变成 文档/file.pdf,必须创建新对象、删除旧对象

R2/S3 API 限制:

  • 不支持重命名操作(rename)
  • 不支持移动操作(move)
  • 只能通过复制(copy)+ 删除(delete)实现

即使是 AWS S3 官方控制台,重命名文件夹也是同样的实现方式。Cloudflare R2 控制台目前甚至不提供文件夹重命名功能。

建议: 如果经常需要重命名文件夹,建议在创建时就想好名字,避免后续大量文件的复制操作。对于包含大量文件的文件夹,重命名的成本较高(耗时 + R2 操作次数计费)。


注意事项

安全建议

  1. 密码安全

    • 请使用强密码,避免使用简单密码如 123456
    • 定期更换密码
    • 不同用户使用不同密码
  2. 权限配置

    • 遵循最小权限原则,只给用户必要的目录权限
    • 敏感文件不要放在访客可访问的目录
    • 定期检查用户权限配置
  3. 分享链接

    • 敏感文件分享时建议设置密码和有效期
    • 定期清理过期的分享链接
    • 注意下载次数限制

费用说明

项目免费额度超出费用
R2 存储10 GB / 月$0.015/GB/ 月
R2 A 类操作100 万次 / 月$4.50 / 百万次
R2 B 类操作1000 万次 / 月$0.36 / 百万次
Pages 请求无限制免费
KV 存储1 GB$0.50/GB/ 月

对于个人使用,免费额度通常足够。大量文件操作(如批量重命名、移动)会消耗较多 A 类操作次数。

已知限制

  • 单文件最大支持 5GB
  • 文件夹重命名 / 移动需要复制所有文件(对象存储限制)
  • 暂不支持文件夹上传(浏览器限制)
  • 搜索仅支持当前目录,不支持全局搜索



致谢


如果这个项目对你有帮助,欢迎 Star ⭐


📌 转载信息
转载时间:
2026/1/2 16:16:55