准备账户
准备 GitHub 与 Cloudflare 账户,开通 R2 并设置 Workers 子域名。已有账户无需重复创建。R2 可能要求绑定付款方式;请自行完成套餐与付款设置。
本教程适用于新实例。现有 Go、Pages 或旧 Worker 实例升级,请使用仓库的迁移与生产部署文档,避免两套服务管理同一桶。
应用默认配额为 9 GB、单文件上限为 8 GiB。R2 免费额度按账户共享,存储、请求和其他桶都会影响账单;应用配额不是账单硬上限。查看 R2 价格。
上传,发出链接。
到期自动清理。
MIT 开源 · 支持 Workers Free
端到端加密:明文只在发送者和接收者的浏览器出现。Cloudflare 接收、保存和返回的都是密文,明文文件密钥不会上传。
发送者浏览器
原始文件本机生成随机文件密钥,按 16 MiB 原文分块,用 AES-256-GCM 加密后上传。
Cloudflare
密文
私有 R2 保存加密数据;D1 保存加密密钥信封。Worker 检查权限、有效期和次数,签发短期下载地址。
云端没有明文文件密钥
接收者浏览器
还原文件用完整链接和可选分享密码在本机解开密钥信封,验证分块后解密保存,并核对完整 SHA-256。
解密材料由你交给对方
完整链接中的 #k=…,加上你设置的分享密码 → 接收者浏览器。片段密钥不随 HTTP 请求发送,也不进入 Parcel API。
文件内容、原始文件名、媒体类型和原文 SHA-256 均被加密。服务端仍可见大小、分享 ID、有效期、下载次数和请求元信息。端到端加密仅适用于 Cloudflare 部署;独立 Go 与连接 Origin 的 Pages 构建保留原有传输协议。
分享链接的 # 后保存随机 32 字节密钥材料。URL 片段不会随 HTTP 请求发送;Parcel 也不会把它加入 API。缺少这部分,接收者无法解包文件密钥,服务器也无法代为恢复。
无密码时,链接材料经 HKDF 派生信封密钥。有密码时,浏览器先用独立随机盐运行 Argon2id,再与链接材料共同经 HKDF 派生,用 AES-GCM 包裹文件密钥和元信息。接收者需要完整链接与所设置的密码。
另一份使用不同盐的密码派生凭据,经 HTTPS 交给 Worker 做在线授权;它不是解包密钥。有效期、次数、撤销和管理员 TOTP 仍由服务端检查。
修改分享密码只重新包裹很小的密钥信封,不重传文件。已经拿到旧文件密钥和密文的人,仍能解密自己的副本;撤销无法收回已保存的文件或密钥。
此机制信任浏览器、设备与实际加载的网页代码。恶意更新的网页、扩展或本机恶意程序仍可能读取端点密钥。 HTTPS 和 Cloudflare 的存储加密继续提供额外保护,不能代替端点可信。
按钮负责创建应用资源。管理员认证和文件跨域权限,按下面的实际控制台页面完成。 截图核对于 。
准备 GitHub 与 Cloudflare 账户,开通 R2 并设置 Workers 子域名。已有账户无需重复创建。R2 可能要求绑定付款方式;请自行完成套餐与付款设置。
本教程适用于新实例。现有 Go、Pages 或旧 Worker 实例升级,请使用仓库的迁移与生产部署文档,避免两套服务管理同一桶。
应用默认配额为 9 GB、单文件上限为 8 GiB。R2 免费额度按账户共享,存储、请求和其他桶都会影响账单;应用配额不是账单硬上限。查看 R2 价格。
点击部署按钮,按 Cloudflare 的引导创建自己的 GitHub 仓库,选择
Worker 名称以及 D1、R2 资源。根目录保持
/,Node 版本使用
24。
构建命令为
npm run build,部署命令为
npm run deploy。部署脚本通过
DB 绑定执行 D1
migrations,并把实际创建的 R2 桶名写入
R2_BUCKET_NAME。
关闭“启用预览构建”。模板与部署命令固定设置
ADMIN_AUTH=totp,省略该运行时变量也默认使用密码加
TOTP。公开分享页供接收者访问。
首次保持
ACTIVE=false。缺少运行时配置时返回
serverless_unconfigured
是预期状态;配置完成前不要对外分享。
管理员使用 Parcel 自带的密码 + TOTP 登录。在 Worker
的运行时变量里设置
ADMIN_AUTH=totp;模板与部署命令会固定设置,省略该变量也默认使用此模式。按下面的步骤完成首次初始化。
Parcel 绑定页
本地生成绑定码你的认证器
每 30 秒更新动态码保存恢复码
8 个恢复码单独保管 · 更换认证器后旧码失效ACTIVE=false。当前部署脚本会自动应用包括
0003_admin_totp.sql 在内的 D1
migrations。
npm run admin:setup-token。命令将随机初始化密钥保存到
.parcel-v3/admin-setup-token.txt,不会打印密钥,也不会覆盖已有文件。将文件内容作为 Worker
Secret
ADMIN_SETUP_TOKEN
保存,去掉末尾换行;保留原
SESSION_SECRET。
/login,输入初始化密钥,设置至少
12 位的管理员密码。用支持 TOTP
的认证器扫描页面上的绑定码,或手动导入密钥;输入认证器显示的
6
位动态码完成绑定。二维码在浏览器本地生成,不使用第三方二维码服务。
ADMIN_SETUP_TOKEN。日常登录只需密码与动态码。管理页“登录安全”可以更换认证器;丢失认证器时,用密码
+ 一个恢复码重新绑定,每个恢复码只能使用一次。
初始化完成后,用新的无痕窗口验证密码 + TOTP
登录、错误凭据被拒绝,以及匿名管理 API 返回 401。然后设为
ACTIVE=true
并部署,再验收上传和公开分享。维护状态允许绑定和登录,但不允许文件传输。
R2 → Overview → Manage API Tokens → Create Account API token。选择 Object Read & Write,仅允许这个应用的桶。记录 S3 Access Key ID 与 Secret Access Key,作为 Worker 的两项密钥保存。
R2_ENDPOINT 是桶设置里的 S3 API
账户地址,例如
https://ACCOUNT_ID.r2.cloudflarestorage.com,不带桶名与尾部斜杠。Worker 的
FILES 绑定、R2_BUCKET_NAME
和凭据允许的桶必须一致。
桶保持私有,不启用公开 r2.dev 或公开桶域名。文件通过短期预签名地址上传与下载。
Worker → Settings → 运行时变量和密钥。普通配置选择变量;以下三项勾选“密钥”:
SESSION_SECRET:独立生成的 64
位十六进制随机值。
R2_ACCESS_KEY_ID:刚创建的 S3
Access Key ID。
R2_SECRET_ACCESS_KEY:配套 S3
Secret Access Key。
node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
在自己的终端生成会话密钥,不要把结果放进 Git、Issue、截图或网页。单独安全备份;后续部署保持不变,直接更换会导致密码校验材料和 TOTP 密钥无法解密,影响分享解锁及管理员登录。
普通变量至少填写 PUBLIC_URL、ADMIN_AUTH=totp、R2_ENDPOINT 和
R2_BUCKET_NAME。PUBLIC_URL
必须等于实际访问的 HTTPS
origin,无路径、无尾部斜杠。首次绑定还需临时 Secret
ADMIN_SETUP_TOKEN;绑定完成后移除。
R2 → 你的桶 → Settings → CORS Policy → Edit。允许的 Origin
精确使用
PUBLIC_URL。下面的配置工具会生成可粘贴的 JSON。
另在 Object lifecycle rules 添加一条仅针对
parcel/v3/ 前缀的未完成 Multipart
清理规则,1
天后终止未完成上传。不要设置已完成对象的独立删除期限,正常过期删除由应用
Cron 与 D1 状态协调。
确认 Cron 为 */5 * * * *,Free
模式保留 WORKERS_PLAN=free、CLEANUP_BATCH_SIZE=1。
选择文件和可选分享密码。浏览器先读取原文件计算完整 SHA-256, 再逐块加密、上传;每块原文为 16 MiB,末块可更小,内存占用不会随文件总大小增长。 空文件也有一个带认证信息的 28 字节密文块。
暂停或刷新时保留网站数据。续传需重新选择原文件,Parcel 会核对完整 SHA-256,而非只信任文件名和大小。已完成块留在 R2, 重试使用新的随机 nonce;浏览器须保留本地上传密钥,任务也须仍在有效期内。
复制包含
#k=…
的完整分享链接,把可选密码分开发送,并留存链接。 分享页的“备份
/ 导入本机分享密钥”可以导出小型加密备份, 使用单独的至少 12
字节备份口令。换浏览器管理密码前先导入备份;
仅凭管理员登录不能找回丢失的密钥或原始文件名。
接收者先在本机解锁,再把通过认证的密文块接收到浏览器 IndexedDB。 接收完成后点“保存解密文件”,逐块校验、解密并流式写入磁盘,不会拼成巨型 Blob。刷新后可从完整缓存块继续;同一有效下载会话的重试不重复扣除下载资格。
本机需同时容纳临时密文与最终原文件,约两倍文件大小并预留余量。 浏览器配额、无痕模式、磁盘余量、下载权限和缓存自动清理都会影响大文件。 长期存储权限可选,不回答或拒绝不会阻止本次接收。 保存期间保持页面打开;确认文件已保存后,可清除本机续传缓存。
创建者浏览器的网站数据中保存本机密钥,不能防住控制该浏览器的人。 清理网站数据或换设备前先备份;本机密钥、完整链接和备份全部丢失后,服务器无法恢复。 旧版未加密 Worker 分享不兼容,需重新上传;升级不会删除现有 D1 或 R2 数据。 Go 与连接 Origin 的 Pages 仍是独立的非 E2EE 模式。
输入应用地址、账户 ID 与桶名。工具仅在当前浏览器计算,不接收任何密钥。
所有内容仅保存在页面内,刷新即可清空。
代码区可滚动查看;复制时会包含完整配置。
R2 → Settings → CORS policy
Worker → 设置 → 变量和密钥
另存三项长期密钥,以及仅用于首次绑定的 ADMIN_SETUP_TOKEN。设置管理员密码、绑定认证器并保存恢复码后,移除初始化密钥。
配置完整后,把 ACTIVE 改为 true 并部署。用一个小文件验证整条链路,再开放实例。
/admin,应显示密码与动态码登录。错误密码或动态码均不能通过;匿名管理
API 应返回 401。
Workers Free 的 CPU 预算为每次请求 10 ms。本地测试不能证明线上 CPU 或真实 R2 配置;生产报 1102 时请检查指标。查看 Workers 限制。
检查
ADMIN_AUTH=totp
与三项长期密钥。SESSION_SECRET 必须为 64 位十六进制;PUBLIC_URL 和
R2_ENDPOINT 必须是无路径、无尾部斜杠的 HTTPS 地址。未初始化时还需
ADMIN_SETUP_TOKEN。
访问域名须等于 PUBLIC_URL,并允许站点保存会话 Cookie。动态码不通过时,检查认证器设备是否自动同步时间;每个 30 秒时间步只使用一次。登录请求超时后,页面会检查是否已建立会话,可按提示进入管理页或重新登录。应用域名变更时,同步更新 PUBLIC_URL 与 R2 CORS;教程站点迁移不改变应用域名。
检查 CORS Origin 与 PUBLIC_URL 完全一致;确认 FILES 绑定、R2_BUCKET_NAME、S3 凭据限定桶一致。账户 API Token 不能代替 S3 Secret Access Key。
Parcel 应用侧的上传创建与进度、完整分享链接、密码修改与密钥备份、 接收者解锁、密文接收和解密保存流程截图都需要按新版重拍。 使用可丢弃的演示文件与密钥,不公开真实完整链接、密码、密钥备份或认证器密钥。
教程保留六张 Cloudflare 配置图:绑定、构建成功详情、R2 凭据、添加密钥、CORS 与生产构建设置。运行时变量由配置工具直接生成。端到端加密不新增服务端文件密钥或 CORS 请求头。TOTP 绑定使用网页示意,无需真实扫码截图。
模板部署使用 --keep-vars,保留控制台普通变量与密钥,并先执行 D1 migrations。不要把生产实例改成首次 CLI bootstrap。升级前备份 D1 与 SESSION_SECRET,阅读版本迁移说明;Worker 回滚不等于数据库回滚。
可以。安装 Node 24 与 Bash,克隆仓库,用 deploy/v3.example.json 建立忽略目录中的配置,准备限定账户权限的管理 Token 和私密的 ADMIN_SETUP_TOKEN,再运行 npm run deploy:bootstrap -- --config .parcel-v3/deploy.json。在 /login 设置密码并绑定 TOTP,保存恢复码、移除初始化 Secret 后, 加 --activate 重跑;脚本确认已绑定才会开放服务。凭据准备、迁移与恢复步骤见仓库文档。