BookBrowser Web阅读器揭秘:epub.js与PDF.js驱动的离线缓存和主题定制系统
[输出文章]
BookBrowser Web阅读器揭秘:epub.js与PDF.js双引擎的离线缓存与主题定制完全指南
BookBrowser 是一个用 Go 语言编写的 Web 电子书服务器,支持 epub、PDF 和 MOBI 格式。它的浏览器内 Web 阅读器由两大开源引擎驱动:epub.js 负责 epub 阅读,PDF.js 负责 PDF 渲染,并内置了离线缓存、阅读进度记忆和主题定制系统。本文将带你快速上手这套阅读器,搞懂它的缓存机制与自定义设置。
🚀 如何快速启动 BookBrowser 并打开 Web 阅读器
只需两步即可让本地书库变成在线阅读站:
- 获取项目(可执行
git clone https://gitcode.com/gh_mirrors/bo/BookBrowser,或直接从 Releases 下载压缩包) - 把可执行文件放到你的电子书目录,运行后默认监听
:8090端口
启动后打开 http://localhost:8090,就能看到按封面卡片展示的书架:
点击任意一本书进入详情页,会出现 Read 按钮。它根据格式分流到不同阅读器,逻辑写在 public/templates/book.tmpl 中:
- epub → 跳转到
epub.js阅读器(ePubViewer) - pdf → 跳转到 PDF.js 的
viewer.html?file=...
📖 epub.js 阅读器:主题、字体与行距怎么调
打开 epub 后你会看到侧边栏,包含目录、搜索、书籍信息和设置四个标签页。设置页就是主题定制系统的核心,界面定义在 public/static/reader/epub/index.html 中,提供 5 组一键切换项:
| 设置项 | 可选项 |
|---|---|
| 主题 Themes | 6 套配色:纯白、纯黑、深灰、米黄、暖夜、深蓝夜 |
| 字体 Font | Arial、Lato、Georgia、Times New Roman、Arbutus Slab |
| 字号 Font Size | 8pt ~ 18pt 共 8 档 |
| 行距 Line Spacing | 1 ~ 3 共 9 档 |
| 边距 Margin | 0 ~ 15px 共 9 档 |
每个选项都是一个"chip"按钮,点击后立即生效,且会写入浏览器 localStorage 持久保存——下次打开自动恢复。点击与存储逻辑见 public/static/reader/epub/script.js。
选中后,applyTheme() 会把背景色、前景色、字体、字号、行距、两端对齐等规则注入到 epub.js 的渲染容器中,直接覆盖书籍内部样式,实现"任意 epub 都能换肤":
💡 小技巧:想一键还原所有设置,点设置页底部的 Reset All 即可清空 localStorage 并刷新页面。
📄 PDF.js 阅读器:开箱即用的企业级 PDF 渲染
PDF 分支走的是另一条路:BookBrowser 内置了完整的 PDF.js viewer(位于 public/static/reader/pdf/web/,含 CJK 字体映射 cmaps、多语言 locale 和全套工具栏图标)。
书籍详情页的 Read 按钮通过 viewer.html?file=/download/xxx.pdf 把 PDF 交给 PDF.js 渲染,因此你自动获得了缩放、搜索、双页模式、旋转、文档属性等 PDF.js 原生能力,且完全由浏览器端处理——服务器只负责按 HTTP Range 提供文件流。
💾 离线缓存揭秘:三层缓存如何记住你的阅读进度
BookBrowser 的"离线体验"其实由三层缓存协同完成:
1️⃣ 阅读位置缓存(localStorage)
每翻一页,epub.js 会触发 relocated 事件,把当前位置的 CFI(通用片段标识符) 存进 localStorage,键为 书籍key:pos:
localStorage.setItem(`${this.state.book.key()}:pos`, event.start.cfi);
再次打开这本书时,started 事件自动读取并跳转回上次位置(script.js)。换浏览器、换设备前,进度都不会丢。
2️⃣ 位置索引缓存(locations)
epub.js 需要"位置编号"来显示进度和实现跳转。阅读器按每 1650 字符生成一次位置索引,生成后立刻序列化存入 localStorage(键为 书籍key:locations-1650),下次打开直接 locations.load() 加载,跳过耗时计算(script.js)。这就是底部状态栏能显示 Loc 1234/5678 的原因。
3️⃣ Service Worker 与 XHR 缓存
- Service Worker:epub 阅读器入口注册了 public/static/reader/epub/sw.js,负责应用更新时自动
skipWaiting并刷新页面,保证你拿到的始终是最新版本。 - XHR 缓存:版本更新检查(public/static/updater.js)用 localStorage 做请求缓存,带时间戳、30 分钟有效期,避免每次打开页面都重复请求接口。
三层缓存让阅读器"首屏快、翻页快、进度不断",这也是 Web 阅读器相比直接打开文件体验更好的关键。
📂 阅读器核心文件在哪里看?
想深入源码,重点看这几个文件:
- epub 阅读器入口页(主题/字体设置 UI):public/static/reader/epub/index.html
- epub.js 封装逻辑(进度、主题、字典):public/static/reader/epub/script.js
- 第三方引擎本体:
public/static/reader/epub/libs/epub.js、public/static/reader/epub/libs/jszip.min.js - PDF.js viewer:
public/static/reader/pdf/web/viewer.html - 服务端路由与书籍模型:server/server.go、booklist/book.go
- 项目文档与截图:docs/index.html
✅ 小结
| 能力 | 实现方式 |
|---|---|
| epub 阅读 | epub.js(ePubViewer) |
| PDF 阅读 | PDF.js viewer |
| 主题定制 | 6 套主题 + 字体/字号/行距/边距,localStorage 持久化 |
| 阅读进度 | CFI 位置 + 位置索引双层缓存 |
| 版本保鲜 | Service Worker + XHR 缓存 |
无论你是想在 NAS 上搭一个家庭书库,还是只想体验一个"能换肤、记得你翻到哪儿"的 Web 阅读器,BookBrowser 的前后端分离式设计都值得一看——服务端只管书架,阅读体验全部交给 epub.js 与 PDF.js 两个成熟的开源引擎。
[输出文章]
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考






