worker.js —— 从「上游原版」到最新版,新增了什么、修了什么、怎么实现的。
时间跨度 2026-08-28 → 2026-09-27(31 天)· 53 份版本副本 · 最近更新 2026-09-27
| 引入 | 类型 | 功能 / 改动 | 说明 |
|---|---|---|---|
| 08-28 | 新增 | 回收站(软删除)trash: 前缀 | 原版删除=永久消失。删前把整棵子树快照到 trash:,R2 实体不立刻删;恢复=反向搬回 |
| 08-28 | 新增 | 访客协作 /shared 可收件 | 把只读分享变成「可收作业」:口令验证 + 直传 + 分片 + 建文件夹 + 配额 |
| 08-28 | 加固 | 节点 API 密钥回退 | 去掉「没配 token 就用管理员密码」这条密码泄漏通道,改为直接关闭节点 API |
| 08-28 | 加固 | SSRF 防护 | 存储节点 URL 原可填内网地址(如 169.254.169.254)→ 只允许公网 http/https |
| 08-28 | 加固 | 登录爆破限流 | 登录接口无限速 → 可跑字典。加失败计数 + 锁定时长 |
| 08-28 | 修复 | 孤儿分片清理误删 | 清理任务会把正在上传中的分片当垃圾删掉 → 加「进行中」判定 |
| 08-28 | 移除 | 全局页脚 | 原作者写在全局外壳里 → 登录/主页/分享页全带着。只保留 /shared 页底部一行免责声明 |
| 08-30 | 新增 | PWA 支持 | manifest + Service Worker + 多尺寸图标,可「添加到主屏幕」全屏打开 |
| 09-01 | 修复 | 分片上传断点续传 | 原版断网=从头再来。resumeKey 找回会话,新增 /api/multipart/status |
| 09-05 | 修复 | 401 守卫白名单 | 原版 bug:/s/xxx 与 /shared 也被踢去登录页 → 分享功能等于失效 |
| 09-06 | 新增 | 版本历史 | 覆盖前把旧实体快照成新 R2 key,一文件一条版本索引。与回收站构成「双保险」 |
| 09-08 | 新增 | 在线预览五件套 | PDF / Word / Excel / PPT / 音视频。单版体量从 388 KB 跳到 608 KB,提升最大的一块 |
| 09-08 | 新增 | 可折叠侧边栏 | 原版只有顶部应用栏,窄屏/手机内容挤成一团;移动端默认收起 |
| 09-08 | 界面 | 页面内弹窗替代原生 | 15 处 alert/confirm/prompt 换成 Material 风格弹窗 |
| 09-09 | 优化 | 回收站列表并发读 | Promise.allSettled 并发化,治「回收站点开要等很久」 |
| 09-10 | 优化 | 目录改名 / 移动批量化 | 原版最严重缺陷:O(N²) 子请求超限被强杀 → 留下新旧两份重复索引。子请求 ≈500 → ≈7 |
| 09-10 | 修复 | 云端改名一条龙 | 把「三步操作」压成双击一次;兼容「云端已改过名」的识别 + 跳过 + 只补本地 |
| 09-11 | 修复 | list-all 的 modified 取值 | 用错字段 → 改名会把整棵树判「云端较新」→ 同步重下约 500 MB。改为内容上传时间优先 |
| 09-12 | 修复 | 孤儿清理漏扫(严重) | 只扫文件前缀 → 点「清理孤儿」会把回收站 + 所有历史版本判为孤儿,勾选即永久丢失 |
| 09-12 | 优化 | 回收站 N+1 → 集合查询 | listRaw() 一条 SQL 取回全部键值:89 条实测 0.95 ms vs 旧写法 ≈18 ms |
| 09-12 | 新增 | 回收站「清理 N 天前」 | 手动按钮而非 cron:量级小、可见可控,避免定时任务误删 |
| 09-12 | 修复 | PWA 图标溢出 | 真根因是 manifest 的 purpose:'maskable' 一行 → 删掉即好 |
| 09-14 | 修复 | 全局搜索(三轮大修) | 修 formatDate is not defined、修匹配数翻倍、结果含文件夹、输入即搜、面板可滚动 |
| 09-14 | 新增 | 搜索只按名称匹配 | 刻意取舍:结果更精准(「必修一」不再被整棵子树淹没),代价是命中文件夹名的文件搜不到 |
| 09-15 | 新增 | 存储用量口径改造 | 口径换成「存储桶物理占用」+ 占用构成 + 月均快照,一眼看出会不会超 R2 免费额度 |
| 09-17 | 加固 | 预览库同源托管 | 5 个库原全走 jsdelivr(可用性 + 供应链双风险)→ 挪到 R2 system/lib/,CSP 得以收紧为纯 'self' |
| 09-17 | 加固 | Office 预览 XSS 清洗 | 全站唯一真正的「数据派生 XSS」入口(Office 解析结果直接 innerHTML,输入是外来文件)→ 白名单清洗 |
| 09-17 | 加固 | 长期会话(删掉存密码) | 原来把密码 base64 存 localStorage = 明文。改为服务端签 30 天令牌 session:v3 |
| 09-17 | 加固 | 安全响应头 + CSP | htmlResponse() 收口全部 9 处 HTML 出口;不能被 iframe 嵌套 / 不能被 object 借道 |
| 09-17 | 加固 | 分享令牌密钥收紧 | 原来拿公开的 share.id 当签名密钥 → 可伪造任意分享访问令牌 |
| 09-17 | 修复 | 大文件没有版本历史 | >512 KB 的文件优先走分布式,而分布式路径没有快照调用点 → 版本列表恒为空(教学 PPT 全在这区间) |
| 09-17 | 修复 | 手机换图「读取失败」 | 三条路(FileReader / arrayBuffer / objectURL)→ 两条路兜底 + 按字节魔法数判型 + 失败三分诊 |
| 09-17 | 修复 | 用量分类瑕疵 | system/lib/ 3.4 MB 原被算进「云盘文件」→ 并入站点资源(总量不变,只是分类修正) |
| 09-18 | 新增 | 「从云盘选图」 | 安卓安装版 PWA 读不到选图器的 content:// 引用 → 绕开选图器,直接从云盘取字节 |
| 09-18 | 界面 | 失败提示改「先给结论」 | 不再摆出两个猜想让用户挑,直接给唯一动作「请改用『从云盘选图』」 |
| 09-19 | 界面 | 手机列表时间列可见 | 旧表格自动布局超宽 → 时间列与操作列被挤到屏外。窄屏改固定布局 + 时间双格式 |
| 09-19 | 界面 | 共享文件夹改名 shared → 共享 | 存储名跟着改,公开网址 /shared 永不改(发给学生的入口) |
| 09-20 | 界面 | 表头「时间」竖排 | 图标字体 flex-shrink:0 逼文字让步 → 文字锁死、让箭头让步 |
| 09-22 | 界面 | 回收站窄屏对齐主界面 | 错位套用了主界面的 nth-child 列序规则 → 改用更高特异性选择器逐列纠正 |
| 09-22 | 新增 | 回收站「时间 ⇄ 大小」切换 | 360px 放不下四列 → 表头加 ↔ 小按钮,箭头永远指向「点了会变成什么」 |
| 09-22 | 界面 | 641–720px 固定布局 | 真凶是共享的 .file-row-name{max-width:400px} 把名称列 min-content 钉在 458px |
| 09-22 | 界面 | 主列表 641–1110px 固定布局 | 主网盘/共享/分享三张表同被钉住 → 溢出又被 overflow-x:hidden 静默裁掉 |
| 09-22 | 界面 | 侧栏抽屉断点 768 → 1000px | 治「769–1000px 名称列只剩 4 个字」;顺手修掉抽屉遮罩残留挡住整页的老 bug |
| 09-22 | 界面 | 回收站 721–1110px 固定布局 | auto 布局把整页撑宽,右端被视口裁掉(时间显示成 2026/09/2) |
| 09-26 | 新增 | 上传进度显示实时速度 | EMA 0.65/0.35 平滑,接入 5 处上传;顺手合并下载端内联的同一算法 |
| 09-26 | 新增 | 分享链接自定义后缀 | 可起一个好记的后缀;没照抄上游——本项目 KV 是 upsert,没有原子性,另写了 putIfAbsent() |
| 09-26 | 新增 | 复制下载直链 | 免密文件直接给出直链(/api/share-download 路由早就存在,只是一直没暴露给用户) |
| 09-26 | 新增 | 文本文件在线编辑 | 新增 /api/text-file:ETag + If-Match 乐观锁(428 / 409 / 413),写回前留版本回滚点 |
| 09-27 | 修复 | 版本历史弹窗打不开 | 浏览器端调用了服务端专属函数 → 红字「加载失败」。从 09-06 上线起坏了 21 天,第一次真点开才暴露 |
| 09-17 | 移除 | 版本更新检查 | 页面加载时去 GitHub 拉 version.json → 国内常被墙,拖慢首屏。删掉后每页少一个外部请求 |
| 09-17 | 移除 | 下载 inline 死参数 | 全项目搜不到任何 inline=1 生成点 → 删除后下载恒 attachment |
| 09-26 | 放弃 | 上游 Hollow 毛玻璃皮肤 + 自定义壁纸 | 上游把接口 GET 放在鉴权之前(猜到路径就能拉到壁纸);皮肤还会覆盖已调好的四套布局 |
| 09-26 | 暂缓 | 分享管理面板 / 分享页预览 / 全选勾选 | 不是不做,是排在三件高感知功能之后。其中的「请求竞态序列号」值得单独抄 |
jsAttr is not defined)点网页端「历史版本」→ 弹红字「加载失败:jsAttr is not defined」。
loadVersions() 跑在浏览器里,却调用了只存在于服务端的 jsAttr() / jsString() → 一执行就 ReferenceError,被外层 catch 吞成一句话。node --check、部署前自检、产物校验全都抓不到(语法合法、特征字符串也还在)。encodeURIComponent(path),而服务端 /api/versions/restore 拿到的是原样字符串(不 decode)→ 即使不报错,中文路径恢复必然 404。attrJs()(只做 HTML 实体转义,别在它里面再包引号——包了点击只求值不调用);参数改用 JSON.stringify() 生成。两处一起修。worker部署前自检.mjs 新增第 4 项「内联脚本误用服务端函数」,判据自动推导,可反向对照(临时副本退回旧写法 → 精准报出 jsAttr();正常源码 0 误报)。/api/versions/restore,15/15 全过。教训:只验 new Function(onclick) 语法会假绿(多包一层引号也能过)。上游 09-15 发布 v1.2.1(跳过 1.2.0,共 102 个差异块 / +689 −61 行)。挑了三件用户可感知度最高的落地。
formatTransferStats() + trackTransferSpeed()(EMA 0.65 / 0.35,与本项目下载端系数一模一样)。接入 5 处:直传 / R2 原生分片 / 分布式 / 共享文件夹直传 / 共享分片(后两处是本项目自有的,上游只有前三处)。顺手把下载里内联的手算 EMA 也合并进同一函数,−6 行。1–64 位小写字母/数字/下划线/短横线,老链接全部仍合法。规则:创建留空 = 随机后缀;编辑留空 = 保持原后缀(不会因为清空输入框被悄悄改成随机)。DB.prepare(INSERT) 靠主键冲突做原子占位;但本项目写 KV 走 ON CONFLICT DO UPDATE 的 upsert,根本没有原子性,照抄就是「看起来有锁、实际没锁」。改为新增 putIfAbsent() —— 不带 ON CONFLICT,只把 UNIQUE / 主键冲突翻译成 false,其余错误照抛(不吞真错误)。publicShare 加 downloadUrl(仅「文件 + 无密码」时给)。该路由本来就存在,只是从没暴露给用户。/api/text-file(鉴权之后):30+ 扩展名白名单;>2 MB → 413;分布式存储直接拒。ETag + If-Match 乐观锁:缺锁 428、锁不匹配 409「文件已被其他操作修改,请重新打开后再保存」。snapshotVersion() 留版本回滚点 —— 上游是直接覆盖,等于网页上改的文件没有版本记录。前端零第三方库:底层 <pre> 画高亮 + 上层透明 <textarea> 接管输入,滚动同步;Ctrl+S 保存。client/src/server.mjs 的 share-create 是逐字段白名单转发(只转 path/ttlSeconds/maxAccesses/password),新字段必须登记,否则被静默丢掉 → 补 suffix,打包 6.9.27。用户拖动窗口逐个发现:回收站很乱 → 时间列被裁成 2026/09/2 → 名称列只剩 4 个字。四轮排查都在治同一个根因家族。
.file-row-name{max-width:400px} —— auto 布局下表格宽 = 各列 min-content 之和,而名称列的 min-content 恰是「400 文字 + 图标 + 间距 + 内边距 = 458px」(实测各档都是 458,纹丝不动)。合计 ≈822px > 容器 → 溢出。table-layout: fixed 让内容 intrinsic 宽度彻底退出计算,表格恒等于 100% 容器宽、与文件名长短无关。nth-child 列序规则(主界面是「名称/大小/时间/操作」,回收站是「勾选/名称/大小/时间」)→ 不换类,改用更高特异性的 .file-list.trash-list ... 逐列纠正。.material-icons-round 图标字体没就绪时会退化成英文单词,一口吃掉 163px(名称区只剩 85px)→ 补 width:1em。getBoundingClientRect().left),别看 DOM 顺序 —— 按 DOM 顺序判会得到假阴性。256+64+300+名称列 330 ≈ 950,取整 1000。改后 769 档名称列 134 → 437px。.sidebar-backdrop.open 是全局规则 → 在窄屏打开抽屉、再把窗口拉宽,侧栏回归常驻但遮罩留着,整页点不动。加 @media(min-width:1001px){display:none!important} 兜底。worker.fetch()(内存 KV stub + HMAC 自签 session:v3 令牌)拿真实 HTML → iframe 精确模拟各档 CSS 宽度量列宽,并出真渲染截图目视(列宽达标 ≠ 不丑)。
2026/09/2,整页被撑宽 42px
「左侧加了复选框,右边的时间没有了……既然没办法同时显示两种,能不能点一下『时间』就变成『大小』?」
⇄ 图标切 / 不做切换),用户选加图标 —— 把「表头文字」这块热区留给将来的排序。↔ 用 order:-1 挪到文字左边 —— 默认「时间 ↔」、点后「↔ 大小」,箭头永远指向「点了会变成什么」。@media(max-width:640px) 内,宽屏 CSS 没有任何规则引用切换 class);与排序独立;与主界面、共享页独立(class 只加在回收站这一个表格上)。
「1080P 显示刚刚好,只是『时间』两个字变成竖排」→ 第三版把箭头隐藏了 → 用户:「箭头看不见就没人知道能点它排序」。
.material-icons-round 自带 flex-shrink:0(图标压不动)→ 空间不足时被压缩的必然是文字;48px 列宽内容盒只剩 40px,而 CJK 的 min-content 只有 1 个汉字宽 → 折成一半一个字 = 竖排。flex:0 0 auto; white-space:nowrap 锁死,要压就压箭头(flex-shrink:1; min-width:0)。手机上文件列表只见名称/大小两列 —— 旧表格自动布局下「文件名不换行 + 全格式时间 + 操作按钮」总宽超出视口,时间列和操作列被挤到屏幕右边界外。要看时间只能切浏览器「电脑模式」。
table-layout:fixed(名称自适应 / 大小 58px / 时间 54px / 操作列隐藏);时间单元格渲染双格式 span(全格式 + 短格式),窄屏切短格式并允许折两行;表头「修改时间」双 span,排序箭头保留。Range(td.getClientRects() 恒为 1,会假绿)。shared → 共享用户根目录是「工作 / 麦芽糖 / 软件 / 生活 / 探索 / 同步」,就它一个英文,不协调。
sharedBase = '/shared' 全部保持 /shared —— 发给学生的那个入口地址不能变。存储名(SHARED_PREFIX)与公开网址本来就是两个变量,这次只动前者。ReferenceError)→ 必须在模板里用 ${jsString(SHARED_PREFIX)} 注入字面量。shared 文件夹就成了普通文件夹 → 用 /api/rename 把它改名(实测该文件夹当时完全为空,影响为 0)。前两轮修复都失败后,用户给出决定性线索:电脑能设、手机浏览器能设、单单装了 PWA 的不能设。
<input type=file> 选完图得到的是 content:// 引用,PWA 进程没有读它的权限 → size=0、arrayBuffer() 抛 NotFoundError。FileReader / arrayBuffer / createObjectURL 三条路全断在同一个权限上 → 不是代码能绕的,只能绕开选图器本身。/api/list 列当前目录(可进文件夹、可回上一级、有面包屑),只列图片;点图后走同源 fetch('/api/download') 拿字节(PWA 里完全正常)→ 复用 canvas 缩图 → 上传。服务端零改动。catch 前缀由「读取失败:」改为「出错:」。手机里「设置 → 外观 → 更换登录页背景图」,选完照片提示「读取失败」;电脑上同样操作正常。
uploadSiteAsset() 改成两条路 —— ① 原样读(≤3 MB 且 MIME 在白名单,桌面一直走这条,保真、保留 PNG 透明);② URL.createObjectURL → <img> → canvas 重编码(<img> 走浏览器自己的加载器,云相册的图也能拿到),顺带等比缩到 1920 / 512。file.type 标签、不信真实字节 —— 手机选图器经常给空标签/怪标签,好好的 JPG 被当成「不认识的格式」赶去走重编码路;而 img.onerror 把三种完全不同的病因全塞进同一句「可能是 HEIC」,没法排障。sniffImageType() 按字节魔法数认格式(JPEG/PNG/GIF/WebP + ftyp 盒品牌判 HEIC/AVIF),file.type 只做兜底;diagnoseAssetFailure() 三分诊:字节读不出 → 「云相册图没下载到本机,先点开原图/存本地」;真 HEIC/AVIF → 「导出 JPEG」;字节正常也认得 → 「渲染失败,换 Chrome/Edge」。外部审计给出问题清单,复核后落地 7 项。
cdn.jsdelivr.net —— 可用性风险(被墙/抽风 → 预览全废)+ 供应链风险(第三方脚本可在你的页面上执行)。改为 R2 同源托管 system/lib/ + 白名单只读路由 /assets/lib/,CSP 得以收紧为纯 'self'。sanitizeDocHtml() 标签/属性白名单 + 删所有 on* + 去 url()/expression() + 协议白名单挡 javascript:。这是全站唯一真正的「数据派生 XSS」入口 —— 站内其余 ~58 处 innerHTML 要么写死字符串、要么已转义。btoa(encodeURIComponent(pwd)) 存 localStorage —— base64 不是加密,等于明文。用户要的是「少输密码」不是「把密码存下来」→ 服务端签 session:v3 令牌,密码永不落地;兼容 v2 避免已登录用户被踢。htmlResponse() 收口全部 9 处 HTML 出口(避免「加了 8 个漏了 1 个」);HSTS 不带 includeSubDomains;下载恒 attachment + nosniff。shareTokenSecret 会回退用 passwordHash 甚至 share.id —— 而 share.id 是公开字符串(就出现在分享链接里)→ 可伪造任意分享访问令牌。改为只从真正的密钥类环境变量取,取不到就不签(fail-closed)。script-src 必须保留 'unsafe-inline'(页面到处是 onclick)→ CSP 拦不住「已注入的内联脚本」。CSP 的价值在 frame-ancestors / object-src / base-uri / 限外域;防 XSS 只能靠清洗。任何「加了 CSP 就安全了」的想法都是错的。inline=1 让访客上传的 HTML 被内联渲染」→ 复核结论是死参数(全项目搜不到任何 inline=1 生成点),严重性被高估,但顺手删掉仍是正确清理。核实「大文件无版本历史」缺口后如实记账,当天修掉。教学 PPT 基本都在这个区间 —— 该功能对主要使用场景是空转的(面板能开、能列,但永远没内容)。
snapshotVersion() 原来只有两个调用点(/api/upload 与 /api/multipart/complete),没有 /api/distributed/complete;而前端 >512 KB 的文件优先走分布式,且 init 里主节点恒在 → 即使一个外部节点都没配也照样走分布式 → 永远走不到有快照的那条路。r2multipart_session_(R2 原生,有快照)/ multipart_session_(分布式,本次补上)/ shared_multipart_session_(访客上传,有意不做)。snapshotVersion() 学会认 manifest(用真实大小做上限判定,否则任何上限都拦不住;contentType 存清单里声明的原始类型);③ /api/versions/restore 加分布式分支;④ 🔴 新增分片保护 VERSION_SRC_PREFIX —— 快照只存清单,而覆盖上传时旧分片会被清理,分片一删历史版本就变成「能列出、下载不了」的坏文件。VERSION_MAX_MB 20 → 60、VERSION_KEEP_MAX 10 → 5(客户端/脚本版默认值同步改 60)。size=1572864B(修前 0 条)→ 再覆盖累计 2 版 → 恢复最旧版 → 下载内容 sha256 与旧版本逐字节一致 → 删完版本后标记计数 0(无 KV 泄漏)。原口径是「云盘内文件总大小 / 配额」,但桶里还躺着历史版本 / 回收站 / 站点资源 → 看不出会不会超 R2 免费额度。
calculateR2Usage() 本来就整桶遍历一遍,顺手按 key 前缀分类累加(历史版本 / 站点资源 / 其他对象 / 云盘文件),不增加任何一次 R2 请求。/api/storage 有 60 s 缓存,改完不要立刻断言分类没生效。原版只能盯着当前目录手翻,文件一多就是瞎。三轮用户实测反馈又暴露三个体验问题。
formatDate is not defined(结果行整个渲染失败)+ 修匹配数翻倍(网格与列表装的是同一批文件,两个容器一起统计了)。/api/list-all 加可选 ?folders=1(不新增路由,同步端不传 → 调用开销与返回体零变化)+ 结果含文件夹 + 输入即搜 + 空态文案按上下文分流。hit(name) || hit(path) 收紧为只看 f.name + 搜索面板可滚动(480 → 760px)。文件夹 8 + 文件 50 收敛到 文件夹 2 + 文件 1。folders=1 时 folders 是 {name,path} 对象数组;而 /api/list 的 folders 是字符串数组。写测试 stub 时必须同形,否则「断言全绿但功能是坏的」。复核原版代码时发现 findAllReferencedStorageKeys() 只扫文件前缀,漏了回收站与版本索引。
collectStorageKeysByPrefix() 消掉「同一件事两份实现」这个根因;补扫回收站 + 版本索引前缀;deleteOrphanStorageKeys() 加双层兜底(前缀白名单物理拒删 + 删除前再反查一遍)。listRaw() 一条 SQL 取回全部键值,返回结构与排序不变 → 调用方零改动。实测 89 条:新写法 0.95 ms vs 旧写法累计 ≈18 ms(还没算跨机房往返)。purpose:'maskable' 一行(安卓按中心 80% 安全区遮罩裁切满幅图)。/api/list-all 的 modified 取值错误曾写成 updatedAt || uploaded —— 而 updatedAt 是条目写入时刻,改名会被刷成 now。
modified 必须是内容上传时间优先 —— uploaded || updatedAt。DB.batch()」—— 子请求 ≈500 → ≈7,实测 2.3 秒完成。09-11 控制台改名按钮「没生效」三层排查(根因是前端引用未定义变量导致 onclick 静默中断)。Promise.allSettled 并发化,治「回收站点开要等很久」(清空后就秒开,这是典型 N+1 症状)。09-12 用 listRaw() 集合查询根治。原版这些格式全都只能下载。教师场景里 PDF / pptx 是最高频的预览需求 —— 这一块是提升最大的。
<iframe> —— iframe 方案在 PWA / Electron 里会挂(Electron 无内置 PDF 插件,白屏)。带翻页 / 缩放 / 适应窗口 / 左右键。.doc(二进制格式)无法解析。a:xfrm 坐标还原版式)。⚠️ 网页端至今仍是自研还原器,补不起「主题/母版继承 + 表格 + 背景图」,属已知待办。Range —— 否则 mp4 要整包下完才能播、不能拖进度条。alert/confirm/prompt 换成 Material 风格弹窗(PWA / 移动端尤其难看)。同名文件覆盖上传 = 旧内容直接消失。云盘最常见的「手滑」。
r2drive:version:<hash>/<id>/<name>);每个文件的版本索引存一条 D1 记录(value 是数组);新增 /api/versions / restore / delete + 网页端面板。/s/xxx(分享链接)与 /shared(访客页)也被踢去登录页 → 分享功能等于失效。PUBLIC_PREFIXES = ['/login', '/s/', '/shared'] 白名单式放行;install401Guard() 被所有页面继承,漏一个就把访客全踢走。/assets/lib/ 就是放在鉴权之前处理来避开的。resumeKey = sha256(路径|大小|mtime) 找回分片会话;/api/multipart/init 支持复用;新增 /api/multipart/status 查已收哪些片;会话 TTL 7 天(对齐 R2 的分片回收策略)。从上游原版(HandsomeMJZ / R2-Cloud-Drive,7,187 行 / 280 KB)跑通并做第一次加固 —— 这一轮同时定下了整个项目的走向:从「能用」到「敢用」。
/shared 从只读变成可收件 —— 口令验证 + 直传 + 分片 + 建文件夹 + 配额;新增两个环境变量。trash: 前缀,R2 实体不立刻删。| 项目 | 处理 | 为什么 |
|---|---|---|
| 版本更新检查checkVersionUpdate | 删除 | 页面加载时去 raw.githubusercontent.com 拉 version.json —— 运行时依赖 GitHub,国内常被墙/超时,拖慢首屏。代价:上游出新版不会自动知道。 |
下载 inline 参数 | 删除 | 全项目搜不到任何 inline=1 生成点 → 死参数。删除后下载恒 attachment,「上传 HTML 再骗人点开」的攻击链彻底不存在。 |
| 双图架构SITE_FAVICON_KEY | 当天回退 | 用户实测「连页头 logo 也变了」—— 本意只是「不让 PWA 图标主体溢出」。真正的根因就是 manifest 的 maskable 一行。教训:默认走最小改动。 |
| favicon 清理临时按钮 | 用完即撤 | 一次性运维操作,不应长期留在界面上。 |
| 上游 Hollow 毛玻璃皮肤 + 自定义壁纸 | 放弃 | ① 上游把两个接口的 GET 放在鉴权之前(为了让登录页也套主题)→ 任何人猜到路径就能拉到壁纸;② 皮肤会覆盖 .file-card / .sidebar / .file-list,与本项目已调好的四套布局正面打架 —— 成本最高、收益最低。 |
| 分享管理独立面板 分享页在线预览 全选圆形勾选 | 暂缓 | 不是不做,是排在后面。⚠️ 其中的请求竞态序列号值得单独抄 —— 本项目分享面板现在是裸 fetch,同样有「旧响应覆盖新渲染」的毛病。 |
docs/图鉴截图/ 并在条目里引用;④ 顶部「关键指标」与「最近更新」日期。docs/图鉴截图/xxx.png),不要 base64 内嵌 —— 文件会迅速变大且没法复用到别处。data-t。docs/client改动全史.md。