Cloud Drive:把私人云盘放进 Cloudflare Pages
项目地址:github.com/willimt/cloud-drive 没有公共演示站。这是给自己的文件用的入口,部署完成后需要密码登录。
我一直想要一个很朴素的云盘:能放文件、能找回来、偶尔给别人发一个链接,仅此而已。它不需要用户体系、后台数据库,也不想为了这点事再养一台服务器。
Cloud Drive 就是在这个前提下做的。静态页面放在 Cloudflare Pages,读写、登录和分享由 Pages Functions 接住,文件和少量状态都放进 R2。桶保持私有,浏览器不会直接碰到 R2;每次访问都先经过应用的鉴权接口。

上图是平时最常打开的页面。路径可以一直点回根目录,列表或网格的显示偏好会被记住;文件的更多操作都收在右侧菜单里,免得界面一开始就挤满按钮。
它适合做什么
这是单密码的私人云盘,适合自己用,或者和少量彼此信任的人共享。所有管理员共用 AUTH_PASSWORD,没有账号、角色、审计日志或多人协作那一套;要做团队网盘,还是应该选有完整权限模型的产品。
在这个边界内,它把日常要用的事情都补上了:
- 新建文件夹、重命名、移动、回收站恢复,以及列表 / 网格视图和批量移动、删除;
- 点击或拖拽上传。同名文件不会覆盖旧文件,会自动换成
文件名 (1).扩展名; - 文件达到 32 MiB 时改用 R2 分片上传。上传进行中可以暂停、继续或取消;失败的分片最多会自动重试三次;
- 全盘搜索至少输入两个字符。目录、搜索结果、分享记录和回收站都是按页加载;
- 图片、视频、音频、文本和 PDF 可以直接预览,Office 文档则老老实实下载;
- 文件或文件夹都能生成分享链接,可加密码、设有效期,也能在“我的分享”里逐个或一次性撤销。
文件夹的移动、回收和恢复会分批处理。文件很多时,页面会提示正在继续处理,而不是让一次请求硬扛到底。已经创建的分享在重命名或移动后会尝试同步路径;移入回收站的项目会让关联分享失效。
分享页长什么样
分享不是把桶公开出去。它只是应用生成的一条 /s/… 链接,访问者拿到的是经过分享校验后的内容。需要密码的链接会单独校验;过期和撤销的链接也不会再读取文件。



分享密码并不以明文保存,记录里只保留加盐后的派生值。管理员登录和带密码的分享都会做限流:同一来源在十分钟内连续失败五次,会被限制十五分钟。它是给私人项目的一层刹车,不是 WAF 或 Access 的替代品。
不需要服务器,仍然需要认真配置
本地开发只需要 Node.js 和 Wrangler。复制一份本地变量文件,填好强密码和另一段随机密钥,然后启动:
npm install
Copy-Item .dev.vars.example .dev.vars
npm run devpowershellAUTH_PASSWORD="换成强登录密码"
SESSION_SECRET="换成另一段随机长字符串"dotenv本地 R2 数据会落在 .wrangler/ 里,删掉这个目录就相当于清掉本地云盘。提交代码前跑一遍:
npm run check
npm testpowershell部署时,创建一个不公开的 R2 桶,在 Pages 项目中把它绑定为 BUCKET,再把 AUTH_PASSWORD 和 SESSION_SECRET 作为加密变量配置进去。项目中的 wrangler.jsonc 还声明了 IMAGES 绑定:它只用于网格里的图片缩略图,没开通图片转换或图片超过 20 MiB 时,云盘仍能使用,只是会显示占位图。完整的本地运行、Pages 配置和验收步骤放在项目的 README 里。
几个不该忽略的细节
- 不要开启 R2 的公共访问,也不要把 R2 API 密钥写进前端;
AUTH_PASSWORD和SESSION_SECRET应该是不同的值。后者变更后,现有登录和分享会话都会失效;- 回收站只是一次软删除,不是备份。永久删除、误删桶或账号异常都救不回来,重要文件仍要另做备份;
- R2 的存储和操作超过免费额度后会产生费用,分片上传会增加写操作。额度和价格以 Cloudflare R2 定价页 为准。
这个项目没有试图把网盘做得无所不能。它只是把文件、分享和恢复这几件事收在一个小小的界面里,省掉一台服务器和一套数据库,也把该留意的边界摆在台面上。