hectorqin
|
7e66582f84
|
perf(pdf): render with PDF.js and authenticated range loading
|
2026-11-07 11:21:27 +00:00 |
|
hectorqin
|
e3cabf4b1f
|
feat(web): add PWA installation and offline app shell
|
2026-09-24 06:34:21 +08:00 |
|
CodeBuddy
|
5e8d14b460
|
fix(web): 用 iframe 承载章节文档,浏览器实测逼出来的四处修正
真机(Chromium,390x844)跑通整条链路后,之前"看起来对"的地方全都露馅了。
这一轮把渲染层按实测重做,四个都是必须修的:
1. **章节必须是真文档,不能是 shadow DOM 里的片段。**
章节里的 <img src> 和 <link rel=stylesheet> 是浏览器自己去请求的,
没法带 Authorization 头。把它们注入宿主文档的结果是每个插图、每个
样式表都 401 —— 书渲染成无样式无图。iframe 是真浏览上下文,它的
子资源请求是普通导航,URL 里带什么就发什么。所以:外壳用 shadow DOM
(挡的是客户端样式往书里漏,这是它真正能挡的方向),书本身用 iframe。
2. **子资源的 token 只能走 query。**
服务端新增 `queryTokenAllowed`,白名单式放行:仅 GET、仅
/api/v1/books/*/assets|cover|content。触发扫描、写元数据这类端点一律
不接受 URL 里的 token —— 那才是真正会泄到日志和 Referer 的地方。
新增 5 个测试固定这条边界。
3. **`column-fill: auto` 需要确定高度,否则根本没有分页。**
body 不设高度时它会撑到内容高度,整章排成一列,scrollWidth 等于
clientWidth —— 翻页手势完全无效,一章只显示一页。修完 390px 宽的一章
是 3732px / 9 页,翻页步长精确 422px(390 + 32 gutter)。
同时去掉 scroll-snap:吸附目标是列边缘而不是我做出来的页边界,
会导致 scrollLeft 落在两页之间、甚至一次跳两页。
4. **`pageWidth` 是上限不是实际宽度。**
手机上 720px 的列比屏幕还宽,同样退化成"一章一页"。取
min(读者设置, 实际宽度)。
另外发现并按格式分流修好的:PDF(kind=document)之前落进了图片翻页器,
读者看到的是一个破图;现在走 PdfReader。
封面 <img> 也漏了 token,一并改成 api.coverUrl()。
顺带把一个设计缺陷拆开了:目录不再从 manifest 的 groups 取。
groups 是传输分窗,它把目录显示成「第 1 章 – 第 40 章」——服务端的分页
边界漏进了 UI。新增 /books/:id/toc,按格式返回真正的目录
(epub 的 spine 标题、txt 的章节、漫画的卷),与分窗互不干扰。
|
2026-09-16 15:28:34 +08:00 |
|
CodeBuddy
|
d0a475919d
|
feat(web): H5 客户端,精排 epub 渲染 + 多格式阅读
用户的三个问题在这里落地:
1. 「H5 是一个完整的客户端」——同一份构建产物既由服务端托管(`/` 直接
就是完整阅读器),也可被 Android 外壳打进 assets 复用,两种宿主只差
一个 serverUrl。
2. 「纯 H5 时 epub 等资源是否需要 iframe 或 shadow DOM」——用 shadow DOM,
但不是为了隔离出版方样式(那做不到也不该做:书必须能给自己排版)。
它挡的是反方向:客户端自身的 CSS 不会漏进书里。iframe 只在 PDF 那一处
用,因为 PDF 需要自己的浏览上下文,理由写在 render/container.ts 里。
3. 「Android 端 epub 用 H5 渲染,其他类型用原生」——按 kind 分流,
capabilities() 明确声明:reflowable 走 WebView,paged/document 在
Android 交回原生。理由写进 reader-view.ts:WebView 每页一个合成层,
300MB 的画册在一台中端机上就是 OOM。
服务端同步配合的两处:
- 资源流式下发 + HTTP Range
- epub 按包内路径寻址、items/manifest 分窗
前端无框架:渲染热路径是命令式 DOM 操作,引框架只会把"最小覆盖 CSS"
的策略搞复杂;最终产物 35KB(gzip 10.7KB)。
|
2026-09-16 14:45:04 +08:00 |
|