PageBand

把 dist 拖进浏览器就上线,拿到一个子域名和一次性密码,下次凭密码覆盖更新。

年份
2026
角色
全部
技术
Cloudflare Workers, R2, D1, React
Status
进行中

上传一个 dist 文件夹,几秒后它在一个 *.pageband.com 的子域名上。没有账号,没有 CI,没有配置文件。

为什么收敛成一个 Worker#

原本的设计是 Cloudflare Pages 放前端、另一个 Worker 管 API。这个方案在写到一半时被一个事实推翻:Pages 不支持通配符自定义域名,而这个产品的全部意义就是 *.pageband.com

于是三种角色进了同一个 Worker——产品首页、发布接口、以及用户发布出来的站点——按 Host 分流。这不是对简洁的偏好,是唯一可行的形状。

10 毫秒#

免费版 Worker 每次调用有 10ms CPU 和 50 个子请求的上限。一个真实的 dist 有几百个文件,所以「把 zip 传给服务端解压」这条路直接不通:解压本身就会超时,逐个写 R2 也会超子请求数。

所以解压发生在浏览器里。前端拆开 zip,然后每个文件一个 PUT 直接流进 R2,六路并发。Worker 每次调用只做一件事——校验签名,把一个流转给 R2。CPU 时间就此和文件数量脱钩。

密码而不是账号#

没有登录。发布成功时返回一个一次性密码,下次拿「项目名 + 子域名 + 密码」覆盖上传,服务端只存加盐哈希。

这里有一个看起来像偷懒的决定:哈希是单轮 SHA-256,不是 bcrypt 或 argon2。理由是密码由服务端生成,约 93 bits 熵。慢 KDF 防的是人类选的弱密码被离线爆破,而在这个熵下爆破本来就不可行,慢哈希只会吃掉那 10ms 预算的绝大部分。如果哪天允许用户自选密码,这个结论立刻失效。

代价#

发布链路没法自动化测试。页面上有人机校验,脚本拿不到有效 token,所以端到端套件里涉及完整发布的 14 项断言只能跳过,靠人工回归覆盖。这是为「不需要账号、又不被机器人刷满」付的价。

第二个代价在浏览器那侧:解压和并发上传都跑在用户的机器上,一个几百兆的 dist 会让标签页明显卡一下。服务端的 CPU 预算是省下来了,成本转移到了客户端,而不是消失了。