轻量私有云存储 · 说明 (v2.3)
基于 Cloudflare Workers + R2 + D1 的轻量级私有云盘,可选接入 KV 共享密码,支持安全短路径分享、游标分页、Range 下载与 /init 自动迁移。
本服务可与
短链接快速访问服务 共用 KV 命名空间与
相同的 JWT_SECRET,实现登录状态互通。一处登录,两处并行管理。
v2.3 主要更新
- 绑定名统一:Worker 使用
R2、DB 和可选的 KV,不再使用 KV_PAN 或 R2_PAN。
- 密码存储互斥:绑定 KV 时只读取
sys_config,忽略 D1 密码;未绑定 KV 时由 /init 将密码写入 pan_config。
- 旧 KV 兼容:支持空的可选
user 字段、纯文本值、数字值及多个旧字段别名;改密时保留共享配置的其他字段。
- 自动初始化迁移:访问
/init 自动识别空数据库、旧版 v2 或最新结构,所有网盘表统一迁移到 pan_*。
- 页面配置:除
JWT_SECRET、DOWNLOAD_SECRET 外不再使用 Worker 变量,运行参数统一保存在 pan_config。
- 对象隔离:新上传对象统一写入 R2 的
pan/ 目录;初始化不复制或移动旧 R2 对象。
- 短路径分享:永久分享与临时下载统一使用
https://域名/key,分享页面直接显示并复制完整链接。
- 安全加固:配置读取失败时拒绝登录;JWT 和下载令牌均采用 HMAC-SHA256;登录失败按 IP 限流;动态列表使用安全 DOM API 渲染。
- 统一分片上传:所有非空文件均使用 R2 Multipart Upload;32MiB 以内为单分片,较大文件按 32MiB 切片并发上传,最大支持 1GiB。
- 全屏拖拽上传:文件拖入页面任意位置都会显示全屏投放提示,松开后自动进入统一分片上传流程。
- 上传一致性:强制校验
Content-Length,容量与每日限额原子预留,对象 key 使用 UUID;取消分片会释放容量,删除使用 D1 outbox 重试。
- 列表扩展:文件、分享和隐藏列表采用游标分页;R2 同步按页暂存,不再一次性把整个桶加载到内存。
- 下载断点续传:支持
Range、206、Content-Range、Accept-Ranges、ETag 和 HEAD;支持 Range 的下载器可继续未完成下载。
- 部署可控:
/init 使用迁移锁与 schema 版本记录,重复执行只校验结构,不覆盖现有数据。
使用场景
- 个人文件备份与同步:随时上传、下载文件,跨设备访问,数据安全存储于 Cloudflare R2。
- 文件分享与分发:生成
域名/key 形式的独立分享链接,可自定义 key、随时隐藏,适合临时或长期文件分享。
- 团队协作共享:通过分享链接和双密码权限控制,小团队内部分发文档、图片、软件包。
- 静态资源托管:绑定自定义域名至 R2 存储桶,作为图床或静态资源 CDN,加速网站访问。
- 临时文件中转:上传大文件生成分享链接,突破邮件附件限制,轻松传递资料。
核心功能
- 文件管理:最大 1GiB 自动分片上传、断点续传、下载、删除,以及安全图片/视频/音频格式的在线预览;预览格式可在管理面板中以标签添加或移除。
- 分享系统:生成 128 位随机永久短路径,列表展示完整 URL,可修改路径、复制或隐藏分享。
- 权限控制:管理员/用户双密码体系,管理面板包含密码修改、网站设置、列表同步、隐藏管理。
- 隐藏功能:管理员可在管理面板恢复或删除隐藏文件;隐藏分享仅从常规列表移除,完整链接仍可复制、访问或下载。
- 存储同步:自动对比 R2 的
pan/ 目录与数据库,补全缺失文件并清理新目录中的无效元数据。
- 智能下载:支持分段读取和缓存校验;可预览文件内联打开,其余文件以附件下载。
- 用量监控:实时显示存储空间、每日操作限额。
主要资源操作
| 操作场景 | KV 读 | KV 写 | D1 读 | D1 写 | R2 A类 | R2 B类 |
| 首页加载 | 0~1(5分钟缓存) | 首次初始化 1 | 2 条查询 | 0 | 0 | 0 |
| 登录 | 1(强制读取最新密码) | 首次初始化 1 | 限流查询 | 失败计数或清理 | 0 | 0 |
| 统一分片上传 | 0 | 0 | 会话与分片查询 | 按分片登记 | 单分片约 3 次;1GiB 约 34 次 | 0 |
| 下载或预览 | 0 | 0 | 最多 1 条查询 | 0 | 0 | 1 次 GET |
| 删除文件 | 0 | 0 | 文件查询 | outbox 与元数据清理 | 1 次 DELETE | 0 |
| 游标列表 | 0 | 0 | 每页最多 21 行 | 0 | 0 | 0 |
| 列表同步 | 0 | 0 | 按 R2 页查询 | 每批最多 50 条 | 每 500 对象 1 次 LIST | 0 |
JWT 验证不读取密码存储;首页站点信息在单个 Worker isolate 内缓存 5 分钟,但每次登录和修改密码都会强制读取当前密码来源。绑定 KV 后不会回退到 D1 密码。
Cloudflare Free 关键限制
| 资源 | 免费额度或限制 | 本项目影响 |
| Workers 请求 | 100,000 次/天 | 每个分片均计一次 Worker 请求 |
| Workers 请求体 | Free 计划上限 100MB | 1GB 必须由浏览器拆成多个请求 |
| Workers CPU / 内存 | 每次 10ms CPU / 128MB 内存 | 分片直接流入 R2,禁止在 Worker 中聚合 |
| R2 存储 | 10 GB-month/月 | 默认总容量设置为 6GB |
| R2 Class A | 1,000,000 次/月 | 创建上传、上传分片、完成上传、DELETE、LIST |
| R2 Class B | 10,000,000 次/月 | 下载与预览 GET |
详细配置教程 (v2.3)
从零部署当前 Worker。R2、DB 为必选绑定,KV 为可选绑定;后台只配置 JWT_SECRET 与 DOWNLOAD_SECRET,数据库由 /init 自动初始化或迁移。
0. 准备工作
- 一个 Cloudflare 账号(注册)
- 一个可绑定的 域名(推荐腾讯云 .cn 域名)
- 域名的 DNS 服务器已修改为 Cloudflare 提供的地址
1. 创建 Cloudflare 资源
1.1 创建 R2 存储桶并绑定域名
- 登录 Cloudflare Dashboard → 左侧菜单【R2】。
- 点击“创建存储桶”,名称如
my-cloud-pan,区域选择“自动”。
- 创建后进入桶设置 → 公开访问 → 自定义域,绑定子域名(如
files.yourdomain.com)(可选,Worker 可直接访问私有桶)。
1.2 创建 KV 命名空间(可选)
- 需要与其他 Worker 共享密码时,进入【Workers & Pages】→【KV】;独立部署可跳过本节。
- 点击“创建命名空间”,名称如
CLOUD_PAN_KV,保存。
- 与短链接服务共用 KV 时,现有
sys_config.password 会直接作为管理员密码;空的 user 字段表示未启用普通用户。
1.3 创建 D1 数据库
- 左侧菜单【Workers & Pages】→【D1】。
- 点击“创建数据库”,名称如
cloud-pan-db。
- 创建空数据库即可,不需要在控制台手工执行 SQL。
Worker 部署后访问 https://你的域名/init。页面会自动创建 pan_* 表,或迁移旧版 v2 的无前缀表;migrations/ 仅作为人工兜底。
2. 创建 Worker 并绑定资源
- 进入【Workers & Pages】,点击“创建应用程序”→“创建 Worker”。
- 命名 Worker(如
cloud-pan-worker),点击“部署”。
- 进入 Worker 编辑页面 → “设置”→“变量和机密”。
- 需要共享密码时,在“KV 命名空间绑定”中添加变量名
KV;不需要时不要创建该绑定。
- 在“R2 存储桶绑定”中添加:变量名
R2,选择你的桶。
- 在“D1 数据库绑定”中添加:变量名
DB,选择你的 D1。
3. 绑定自定义域名到 Worker
- 进入 Worker 详情页 →“触发器”→“添加自定义域”。
- 输入你的域名(如
pan.yourdomain.com),Cloudflare 自动配置 DNS。
- 等待几分钟后通过该域名访问云盘。
4. Secret 与 /init 配置
在 Worker 设置 → 变量和机密中,只添加以下两个 Secret:
/init 初始化口令:点击 JWT_SECRET 值右侧的复制按钮会生成一个新的 32 字符随机密钥。将复制出的同一个值同时保存为 Worker 的 JWT_SECRET,并在 /init 请求中作为 initSecret 使用;再次复制会生成新值,需要同步更新两处。
安全提醒:
JWT_SECRET 与 DOWNLOAD_SECRET 均必须设置,长度至少 32 位,并保存为 Secret。
- 不要再添加
ADMIN_PASSWORD、USER_PASSWORD 或上传限额等普通 Worker 变量。
- 任一签名密钥缺失或过短时 Worker 会拒绝签发令牌,不会回退到内置默认值。
- 部署 Worker 后访问
https://你的域名/init。
- “初始化口令”填写
JWT_SECRET。有 KV 时读取或修复 sys_config;无 KV 时在 pan_config 初始化密码。
- 没有有效现有密码时需输入 6-128 位管理员密码,不限制字符种类;普通用户密码可留空。
- KV 绑定存在时数据库密码键会被删除,登录和改密不会回退到 D1。
- 页面会创建或迁移全部
pan_* 表,并写入默认 pan_config。
- 管理员登录后在“站点配置”修改容量、上传上限、每日限额、下载时效和预览格式。
5. 纯 Worker 1GB 分片上传
当前版本所有文件统一使用 R2 Multipart Upload,不再保留单请求上传 API,也不再配置单请求上传上限。浏览器固定按最大 32MiB 分片,经多个 Worker 请求流式写入 R2;不需要独立服务器、Pages Functions、Queues 或 Durable Objects。
- 客户端:使用原生
Blob.slice(),最大 32MiB/片、并发 3。小文件使用一个分片,1GiB 文件共 32 片。
- 初始化:
POST /api/multipart/create 校验 JWT、文件名和总大小,原子预留容量,在 R2 的 pan/ 目录创建 multipart upload,并把会话写入 pan_multipart_uploads。
- 传片:
PUT /api/multipart/part?session=...&part=... 将 request.body 直接传给 uploadPart(),Worker 不调用 arrayBuffer(),只把返回的 etag 写入 D1。
- 断点续传:
GET /api/multipart/status?session=... 返回已完成 part number;浏览器通过 localStorage 记住同一文件的会话,只重传缺片。
- 完成与取消:
POST /api/multipart/complete 按 part number 合并并写入文件表;POST /api/multipart/abort 终止 R2 会话并释放预留容量。
- 清理:会话保留 7 天。创建新会话或执行列表同步时会清理过期记录;R2 端仍建议保留 7 天自动终止未完成 multipart 的生命周期规则。
R2 要求除最后一片外每片至少 5MiB,最多 10,000 片。32MiB 方案上传 1GiB 约产生 34 次 R2 Class A 操作和约 35 次 Worker 请求,适合 Free 计划。完整限制见
R2 Upload Objects。
6. 部署与验证
- 将 Worker 代码完整粘贴并部署,再访问
/init 完成 D1 初始化或旧版 v2 迁移。
- 确认必选的
R2、DB 绑定及 JWT_SECRET、DOWNLOAD_SECRET 已生效;共享密码时再确认可选的 KV。
- 有 KV 时使用
sys_config 密码;无 KV 时使用 /init 写入 pan_config 的管理员/普通用户密码。
- 确认新上传对象 key 以
pan/ 开头;/init 不会复制或移动旧 R2 对象。
- 登录令牌保存在当前标签页的
sessionStorage,刷新可恢复;关闭标签页或点击退出会清除本地令牌。退出不会服务端吊销已签发 JWT,JWT 最长 2 小时后到期。
- 创建分享后,确认列表显示
https://你的域名/key 格式的完整链接,并测试复制和访问。
- 用音视频测试
Range 请求;隐藏分享应从常规列表消失,但原链接仍返回文件,并验证列表的上一页、下一页与“更多”。