OpenList 接入 File Viewer:浏览器预览、同源鉴权与静态资源部署实践
自建网盘解决了“文件放哪里”,查看文件却经常还要绕一圈。收到 Pages 文档先找一台 Mac,想看 DWG 先下载,设计目录里的 PSD 也只能根据文件名猜内容。文件已经在网盘里,人却没有真正开始阅读。
我最近把自己维护的 File Viewer 接进 OpenList,想把这一步接顺。本文介绍的是公开的集成分支,验证基线为 OpenList 4.2.7、File Viewer 3.2.2。它需要构建并部署配套前端,不是原版 OpenList 设置里填一个地址就能启用的功能。

先决定哪些预览应该保留
我没有把所有后缀都交给同一个新入口。图片、音视频、PDF、文本和压缩包继续优先使用 OpenList 原生预览;Office、CAD、OFD 和设计资料等增强格式,再按路由交给 File Viewer。文件管理、存储挂载、分享和下载仍由 OpenList 负责。
当天部署的能力目录登记了 283 个去重扩展名、49 条预览链路。其中包含原生优先类型和实验性能力,这个数字不表示 283 套独立解析器,更不表示任意文件都能完整还原。Pages、Numbers、Keynote 已有查看入口;Keynote 目前是静态页面,表格公式读取保存结果。部分设计文件展示保存的预览或结构信息,需按矩阵逐项判断。

部署的是一份完整前端制品
这套集成的前端源码位于 flyfish-dev/openlist-web 的 flyfish 分支。构建机准备 Node.js 24,pnpm 版本由仓库锁定。下面是本次使用的构建过程:
git clone --branch flyfish --single-branch \
https://github.com/flyfish-dev/openlist-web.git
cd openlist-web
corepack pnpm install --frozen-lockfile
corepack pnpm lint
corepack pnpm test:flyfish
NODE_OPTIONS=--max-old-space-size=12288 \
corepack pnpm build
构建前会生成支持矩阵,并复制匹配版本的 Worker、WASM 和字体。交付时保留整个 dist/。只替换 JS 或首页,会把代码和运行时资源拆成两个版本,开发环境能打开也无法证明线上正确。
命令里的 12 GiB 是 Node 构建堆额度。可以在工作站或 CI 上构建,再把静态产物交给 NAS;它不表示服务器运行 OpenList 必须长期占用这些内存。
容器部署时,将完整内容放到宿主机 /srv/openlist/web/,在现有服务上添加只读挂载:
services:
openlist:
volumes:
- /srv/openlist/web:/opt/openlist/web:ro
随后只修改原有 config.json 中的 dist_dir,设为 /opt/openlist/web,保留其余配置、数据目录和存储挂载。本次验证采用 HTTPS 域名根路径,并保留后端动态配置注入;子路径与跨域 CDN 需要另外验收。
200 响应可能是错误内容
预览白屏时,我会先检查资源请求。一个 Worker 地址返回 200,响应体却是 SPA 的首页,浏览器照样无法执行。WASM 还要核对内容类型和响应长度,不能仅看状态码。
配套后端仓库 flyfish-dev/openlist 的 flyfish 分支,在 tools/flyfish/ 中提供了静态资源与 MIME 类型示例。按实际目录调整后,将对应资源配置引入现有 HTTPS server:
include /etc/nginx/snippets/flyfish-preview-assets.conf;
已有同类 location 时先合并,再检查、重载 Nginx。文件和 API 请求仍转发给 OpenList,只有明确的静态资源路径交给静态目录。验收时从 Network 复制真实资源路径,分别查看响应头和开头内容,确认 Worker 得到脚本、WASM 得到二进制,而非登录页或首页。

文件解析放在浏览器,权限仍要走后端
浏览器承担新增预览的解析和绘制,服务器不必运行文档转码进程。但鉴权、存储读取、文件传输和静态资源分发仍然存在。文件走代理时,也会消耗服务器带宽,不能把“免服务端转码”理解成服务器零开销。
增强格式使用 OpenList 同源授权链路。需要配置的格式从构建后的目录读取,不维护第二份手写后缀清单:
node --input-type=module -e '
import { readFileSync } from "node:fs";
const catalog = JSON.parse(readFileSync(
"public/flyfish/format-catalog.json", "utf8"
));
console.log(catalog.preferredExtensions.join(","));
'
将输出与现有 proxy_types 合并、去重,保留旧条目。分享页可按需要开启 share_preview 并关闭 share_preview_download_by_default;压缩包的 share_archive_preview 单独决定,不随普通文档一并开放。
会话复用也必须重新检查权限
公开小文档样例验证过返回目录再打开同一文件的场景:预览实例复用,搜索内容保留。这比反复下载、解析更接近实际阅读习惯。
复用有上限:默认最多 3 个页面、闲置 5 分钟、单个输入文件不超过 8 MiB,估算保留预算 64 MiB,低内存设备更严格。这不是整个浏览器的内存上限。大文件、GPU 和流式预览关闭后释放,文件正文也不长期写进浏览器数据库。
再次打开前仍检查文件信息和权限。退出、换账号、访问被拒绝或显式刷新,应清理对应状态。保留一个页面实例,不能变成绕过授权的捷径。
验收从自己的常用文件开始
建议先试一份 Word、一份 Apple 文档、一张图纸或一个模型、一份设计资料,以及一条有密码或过期限制的分享。既检查能否看见内容,也检查资源请求、返回后的状态、退出后的访问行为。实验性格式用实际文件验收,不根据扩展名做结论。
前端采用 MIT,配套后端采用 AGPL-3.0,依赖遵循各自许可证;旧二进制 PPT 路径的上游水印保留。公开体验和两份仓库入口集中在 Flyfish Drive。这次集成希望解决的事情很具体:找到文件之后,能够在原来的网盘里继续把它看完。
浙公网安备 33010602011771号