OpenList 是一个多功能的目录列表工具,支持数十种网盘文件挂载和文件预览/下载/分享等功能
本仓库是官方 OpenListTeam/OpenList 项目的 TypeScript + Serverless 架构移植版
基于 Cloudflare Workers / EdgeOne Cloud Function / Alibaba Cloud ESA 运行
📘 使用文档 · 🌏 使用文档(中国大陆) · ⚖️ 使用条款 · 🔒 隐私政策
English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Français | Deutsch
点击下方按钮,即可将本项目一键部署到对应平台:
Important
- 若Cloudflare提示
无法获取存储库内容,则您需要先Fork本项目,再通过连接到Github仓库功能部署 - 部署完成后配置环境变量: EdgeOne:国际站 · 中国站;Cloudflare:Worker 后台,环境变量:
DB_FORMAT: 数据存储格式:map(默认,整对象JSON) /key(分key存储) /sql(关系表,与Go后端一致)DB_DRIVER: 数据库驱动:auto(默认,自动检测) /blob(EdgeOne Blob) /cfkv(CF KV API) /kv(KV binding) /d1(Cloudflare D1) /mysql- 其余可选变量参考详细部署指南:Cloudflare · EdgeOne · ESA
OpenList 是一个运行于边缘计算平台的多存储聚合文件列表与管理系统,可将分散在不同网盘、对象存储与协议服务中的文件统一到一个界面,进行浏览、预览、下载与管理。
OpenList-Worker 是官方 OpenListTeam/OpenList 项目的 TypeScript + Serverless 移植版,后端由 Go 重写为运行于 Workers 的 TypeScript 服务,前端保持一致的界面与交互体验。
内置 78 个存储驱动,开箱即用地挂载各类存储后端:
- 国内网盘:阿里云盘(开放平台/分享)、夸克网盘(开放平台/UC TV 版)、百度网盘(相册)、115 网盘(开放平台/分享)、123 云盘(开放平台/分享)、天翼云盘(189/PC/TV)、中国移动云盘(139/和彩云)、沃家云盘、迅雷云盘、腾讯微云、蓝奏云、PikPak(分享)、豆包网盘、光亚盘、超星小组网盘、联想 NAS 分享、Teambition 网盘、WPS 网盘、阿里文档、HalalCloud、MediaTrack 等
- 国际网盘:Google Drive(相册)、OneDrive(应用/分享链接)、Dropbox、MEGA、MediaFire、Proton Drive、Yandex Disk、Degoo、Bunny Storage、TeraBox 等
- 对象存储:S3 兼容(AWS/OSS/COS/MinIO 等)、又拍云 USS、Azure Blob、WebDAV、FTP、SFTP、SMB、IPFS 等
- 代码托管:GitHub、GitHub Releases、CNB Releases
- 网盘程序:OpenList(分享)、AList V3、Cloudreve V3/V4、Kodbox(可道云)、Seafile、Teldrive、Febbox 等
- 其他驱动:网易云音乐、Misskey、Emby、Cloudflare 图床等
除上述真实存储外,还提供 Local、Alias、UrlTree、AutoIndex、Strm、Crypt、Virtual、Chunk 等虚拟/功能型驱动,可用于本地挂载、地址别名、URL 列表、加密存储与分片等场景。
- 文件浏览:统一的目录树浏览,支持图片、视频、音频、文档、代码、压缩包等格式在线预览。
- 上传下载:跨存储的上传、批量下载、流式传输与直链跳转。
- 文件分享:生成带有效期、密码与权限控制的分享链接,支持匿名访问与目录分享。
- 全文搜索:在已索引的存储中快速检索文件。
- 离线任务:后台任务队列,支持批量操作与异步处理。
- 外部接口:将聚合存储以 WebDAV 或 S3 兼容协议对外暴露,便于挂载到第三方工具。
- MCP 服务:提供 Model Context Protocol 端点,可被 AI 助手等客户端集成调用。
- 并发去重(singleflight):同一时刻相同的目录列表 / 元信息请求只向上游网盘发起一次,其余请求复用同一结果;一个部署存在多个 isolate,因此除进程内合并外,还会用数据库表
x_singleflight做跨实例协调(详见并发去重)。
- 权限管理:基于角色的访问控制(RBAC),支持用户分组、目录级读写权限与配额。
- 认证方式:内置账号密码,支持TOTP验证、WebAuthn/FIDO登录、SSO单点登录与 LDAP 目录认证。
- 安全加固:JWT 会话、CSRF 防护、点击劫持防护(X-Frame-Options)、内容安全策略(CSP)。
- 健康检查:提供
/health存活探针与/healthz就绪探针,可用于监控与告警。
- 运行平台:Cloudflare Workers、腾讯云 EdgeOne Makers、Vercel、Serverless 及 Node.js 容器环境。
- 数据存储:Cloudflare D1(SQLite)为主,同时支持 MySQL、MariaDB、PostgreSQL、SQL Server。
- 持久缓存:Cloudflare KV / EdgeOne Blob(可选),用于配置持久化与缓存。
- 一键部署:支持 EdgeOne、Cloudflare Workers 等平台的一键部署按钮+初始化。
- Node.js 18+(推荐使用 pnpm)
- Cloudflare 账号(用于部署到 Workers)
# 1. 安装依赖
pnpm install
# 2. 编辑 wrangler.jsonc / .env,配置 JWT_SECRET 与存储(KV/D1 在控制台绑定)
# 3. 启动开发服务器(自动拉取官方前端并运行 Worker)
pnpm run dev:unified
# 或仅运行 Worker(不拉取前端)
pnpm run dev:worker# 一键部署:确保 KV namespace 存在 → 拉取官方前端 → 部署到 Cloudflare Workers
pnpm run deploy
# 或直接部署 Worker(跳过 KV 检查与前端构建)
pnpm run deploy:worker- 运行环境:Cloudflare Workers(Edge Computing)
- Web 框架:Hono.js
- 数据库:Cloudflare D1(SQLite)/ 支持 MySQL、MariaDB、PostgreSQL、SQL Server
- 缓存:Cloudflare KV(可选)
- 语言:TypeScript
- 构建工具:Wrangler、esbuild
- 框架:React 19 + TypeScript
- UI 库:Ant Design / Material-UI
- 构建工具:Vite
DB_FORMAT(数据存储格式)
map(默认):整对象 JSON 格式,适用于 KV/Blob 等简单存储key:分 key 存储格式,每个实体一条记录(如users_1),避免大 JSONsql:关系数据库表格式,与 Go 后端完全一致,适用于 D1/MySQL
DB_DRIVER(数据库驱动)
auto(默认):自动检测可用驱动(优先级:mysql → d1 → kv → cfkv → blob → do)blob:EdgeOne Blob Storage(SDK)/ ESA Blob(binding)cfkv:Cloudflare KV REST API(需配置CF_ACCOUNT、CF_KV_UUID、CF_API_KEY)kv:KV 存储(binding 名固定为KV;EdgeOne Node 云函数自动走 HTTP 代理模式)d1:Cloudflare D1(SQLite)do:Cloudflare Durable Objects(SQLite)mysql:MySQL(仅 Node.js 容器)
DB_CIPHER(敏感字段落盘算法,默认不加密)
none(默认):不加密,敏感字段与普通 JSON 一样明文落盘aes-256-gcm:HKDF-SHA256 派生一把 AES-256-GCM 密钥(enc:v2:) —— 既有加密部署写入的形态,开销最低,开启加密时推荐aes-256-gcm-pbkdf2:AES-256-GCM,密钥由 PBKDF2-SHA256(10 万次迭代)逐字段派生 (历史enc:v1:envelope,抗弱口令但每次读写都很慢,仅建议用于兼容)aes-256-cbc-hmac:AES-256-CBC + HMAC-SHA256(enc:v3:,Encrypt-then-MAC)chacha20-poly1305:ChaCha20-Poly1305(enc:v4:,RFC 8439,纯 JS 实现; WebCrypto 全平台都没有 ChaCha20,故自带实现并通过 RFC 官方向量验证)des-cbc-hmac/3des-cbc-hmac:DES / 3DES-CBC + HMAC-SHA256(enc:v5:/enc:v6:) —— 仅用于兼容/互操作:单 DES 有效密钥只有 56-bit(可被暴力破解),3DES 已被 NIST SP 800-131A 弃用(64-bit 分组 + Sweet32)。选用时后端会打印一次性告警, 请勿用它们保护真实数据。- 别名(大小写无关):
gcm/hkdf/v2、pbkdf2/v1、cbc/v3、chacha20/v4、des/v5、3des/tripledes/v6、off/plain;无法识别时告警并回退none
几种算法的 CPU 特性(实测,120 字节字段,Node 22)
| 算法 | 单字段耗时 | 说明 |
|---|---|---|
aes-256-gcm |
~30 µs | WebCrypto 原生(调用开销为主) |
chacha20-poly1305 |
~18 µs | 纯 JS,小字段下反而更快 |
aes-256-cbc-hmac |
~60 µs | 两次 WebCrypto 调用(加密 + HMAC) |
des-cbc-hmac / 3des-cbc-hmac |
~0.26 ms | 纯 JS(crypto-js) |
aes-256-gcm-pbkdf2 |
~27 ms | 每字段 10 万次 PBKDF2(历史包袱) |
为此后端内置两项优化(对功能无影响):① 密钥派生结果在进程内缓存,同一 isolate 只派生一次;② 未变化字段跳过重新加密 —— 明文、算法、密钥都没变时 直接复用上次的密文,因此「改一个设置」不会触发全库重新加密(对 PBKDF2/DES 这类昂贵算法尤为明显)。
推荐配置组合:
# Cloudflare Workers + D1(推荐)
DB_FORMAT=sql # 也可用 map / key
DB_DRIVER=d1 # 需在 wrangler.jsonc 的 d1_databases 里绑定名为 DB
# EdgeOne + Blob(推荐,零配置)
DB_FORMAT=map # 或 key
DB_DRIVER=blob
# Cloudflare Workers + KV(必须先绑定 KV,见下方【方案 A】)
DB_FORMAT=map # 或 key
DB_DRIVER=kv # 需打开 wrangler.jsonc 的 kv_namespaces,绑定名必须恰好是 KV;
# 未绑定却显式写 kv 会直接报错(不做回退)
# EdgeOne Node 云函数 + KV(还需额外部署 Edge Function 代理)
DB_FORMAT=map # 或 key
DB_DRIVER=kv
EO_KV_URLS=https://<你的部署域名> # 代理地址(也可由请求 origin 自动注入)
JWT_SECRET=<32 字符以上> # 代理鉴权,需与 Edge Function 侧一致
# 远程访问 Cloudflare KV(HTTP API,无需 binding)
DB_FORMAT=key
DB_DRIVER=cfkv
CF_ACCOUNT=your_account_id
CF_KV_UUID=your_namespace_id
CF_API_KEY=your_api_token不确定用哪个就保持
DB_DRIVER=auto(默认,自动探测)。 显式指定驱动时不做回退:该驱动不可用会直接拒绝请求并给出可操作原因(含 「自动探测会选哪个驱动」,照抄即可),/api/public/env_check与/api/public/init_status也会显示同样的原因和一行修复建议, 避免「以为在用 KV、实际写进了别的后端」。 非法「驱动 × 格式」组合(如DB_FORMAT=sql+DB_DRIVER=kv)同样只报错, 不会自动改驱动或格式。
关于 DB_CIPHER 的补充说明:
- 加密只作用于
storages[].addition(网盘凭据)、敏感settings、users[].password、users[].otp_secret;内存中始终为明文,其余逻辑(驱动、路径解析、管理接口)不受影响。 none只表示「不加密数据库字段」,不影响其它任何行为:JWT 令牌签名仍需一把 跨实例/跨冷启动一致的共享密钥,若未通过环境变量JWT_SECRET提供,安装向导仍会 自动生成并持久化openlist_encryption_secret(与加密是否启用无关)。- 密文带版本前缀(
enc:v1:~enc:v6:),读取时按前缀自动识别算法, 与当前配置无关。因此:- 从加密切回
none(或升级后不再配置DB_CIPHER):既有密文仍能正常解密, 并在下一次配置保存时自动转为明文(逐字段迁移,无需任何手动步骤); - 更换算法:既有密文按旧算法解开,下次写入按新算法落盘;
- 既有的明文数据(无前缀)原样返回,升级不会丢数据。
- 从加密切回
- 加密算法选择是正交的一维,不改变
DB_DRIVER/DB_FORMAT的语义。 - 取值无法识别时回退
none并在日志告警(不会静默启用某个算法);/api/public/env_check的config.db_cipher会回显当前生效值。 - AES 三种算法基于 WebCrypto(各平台原生);
chacha20-poly1305与des/3des因 WebCrypto 不提供对应算法而使用纯 JS 实现 —— 全部在 Cloudflare Workers / EdgeOne Node 云函数 / ESA / Node.js 上行为一致(不依赖node:crypto)。
向后兼容:
DB_DRIVER=json自动转换为DB_FORMAT=map+ 自动检测驱动- 未配置
DB_CIPHER时不再对敏感字段加密(旧版本默认加密)。升级已有部署时: 存储中的enc:v1:(PBKDF2)与enc:v2:(HKDF)密文仍会按前缀自动解密、保持可读, 并在下一次配置保存时自动转为明文;如需继续加密,显式设置DB_CIPHER即可 (DB_CIPHER=aes-256-gcm与既有加密部署的写入形态一致)。
表名对齐(仅 SQL 格式):
sql 格式采用列式表,命名策略与 Go 后端的 GORM 一致(snake_case + 复数表名 + 前缀):
| Go 结构体 | 表名 |
|---|---|
SettingItem |
x_setting_items |
SharingDB |
x_sharing_dbs |
Storage |
x_storages |
User |
x_users |
Meta |
x_metas |
| (仅 TS) | x_plugins |
前缀固定为 x_(与 Go 后端默认值一致)。要与 Go 后端共享同一物理数据库,无需额外配置。
本项目实现了两级持久缓存(参考 OpenList.ts):
- 文件树缓存:
/api/fs/list、/api/fs/get、/api/fs/dirs优先从缓存读取目录树, 只有缓存未命中(或已过期)才会去请求网盘 / 对象存储; - 下载链接缓存:
/d、/p等下载链路复用驱动换取的直链, 重复下载 / 预览时不再重新签名或重新换链(网盘换链通常最贵、最易被限流)。
默认只向数据库启用:缓存与业务数据走同一条存储链路(即 DB_DRIVER 指向的
后端),因此「什么都不配」就等于「用数据库做缓存」。想要改用 / 额外启用 KV、
Blob 等专用后端,必须显式添加环境变量(不会自动探测、不会自动回退):
CACHE_ENABLED(总开关)
true(默认):启用两级缓存false:完全关闭(等同于CACHE_DRIVER=none)
CACHE_DRIVER(缓存后端)
db(默认):与业务数据同一个后端(DB_DRIVER解析结果,如 D1 / KV / Blob / MySQL)kv:Cloudflare KV 或 EdgeOne KV(binding 名固定为KV)blob:EdgeOne Blob SDK / ESA Blobcfkv:Cloudflare KV REST API(需CF_ACCOUNT、CF_KV_UUID、CF_API_KEY)do:Cloudflare Durable Objectsmemory:进程内存(仅本地调试,重启即失)none:关闭缓存- 支持逗号分隔的多后端(读按顺序命中,写全部铺开),例如:
db,kv—— 数据库 + KV 双写,读优先命中 KVkv,blob—— 只用两个专用后端
- 显式配置但该后端不可用时:跳过并告警,不会悄悄换成别的后端; 若最终一个都不剩,缓存自动降级为「不缓存」(请求照常走真实存储)。
CACHE_FILE_TREE / CACHE_DOWNLOAD_LINK(分级开关)
CACHE_FILE_TREE默认true;设为false可单独关闭文件树缓存CACHE_DOWNLOAD_LINK默认false:部分网盘的直链 TTL 很短(分钟级 甚至更短),缓存复用容易把已失效的直链发给用户(表现为 403/404)。 确认所用网盘的直链有效期足够长后,再显式设为true开启
CACHE_TTL(文件树缓存时长,分钟)
0(默认):跟随存储级cache_expiration(默认 30 分钟, 可被该存储的custom_cache_policies按路径覆盖)>0:全局覆盖所有存储的文件树缓存时长- 存储级
cache_expiration=0或路径级策略命中0时,该目录永不缓存
CACHE_LINK_TTL(下载链接缓存时长,分钟)
- 默认
5。直链通常自带有效期,取值需保守:缓存过久会把已失效的链接 交给浏览器(表现为 403/404)。设为0可关闭链接缓存。
CACHE_EXCLUDE_DRIVERS(不参与缓存的驱动)
- 默认
virtual,alias,url_tree,strm,chunk—— 这些驱动不产生远程 IO, 缓存没有收益且只会让结果变陈旧 - 传空字符串表示不排除任何驱动
CACHE_PREFIX(缓存键前缀)
- 默认
openlist_cache,用于与业务数据键(openlist_config、users_1等)隔离 - 仅允许
[A-Za-z0-9_](最长 64 字符):前缀会成为 KV 键的一部分,含其他 字符时所有缓存写入都会失败;非法取值回退默认值并告警
失效与一致性:
- 写操作(mkdir / rename / remove / move / copy / put)会立即失效受影响的 路径与其父目录缓存;
- 存储配置变更(更新 / 启用 / 禁用 / 删除)会清空该存储的全部缓存;
- 缓存只存「驱动层结果」,权限、meta 密码、隐藏规则、下载签名都在请求时 实时计算,因此缓存不会造成越权。
管理接口:
GET /api/admin/cache/status—— 生效配置、实际后端、各级缓存条目数POST /api/admin/cache/clear—— body{ type?: "file_tree" | "download_link", storage_id?: number }POST /api/admin/storage/refresh—— 刷新(清空)全部存储的文件树缓存POST /api/admin/storage/refresh_one?id=<id>—— 刷新单个存储的文件树缓存
缓存状态也会回显在
/api/public/env_check的cache字段中, 便于确认「缓存实际落在哪个后端」。
JWT_SECRET:JWT 令牌签名密钥(必填),同时用作可选的字段加密密钥与定时任务鉴权DB_CIPHER:敏感字段落盘算法(可选,默认none不加密):none/aes-256-gcm(推荐)/aes-256-gcm-pbkdf2/aes-256-cbc-hmac/chacha20-poly1305/des-cbc-hmac/3des-cbc-hmac(后两者仅兼容用途,不安全)ADMIN_PASS:初始管理员密码(可选,设置后跳过安装向导自动初始化 admin)
同一时刻对同一存储、同一路径的重复读请求(目录列表、元信息)只向上游发起一次调用, 其余并发请求等待并复用同一结果,用于规避网盘限流与无谓的 CPU 消耗。
| 变量 | 默认值 | 说明 |
|---|---|---|
SINGLEFLIGHT |
auto |
auto:有 SQL 库(d1/mysql/do)时用表协调,否则退回进程内;db:强制用表;memory:仅进程内;off:关闭 |
SINGLEFLIGHT_HANDOFF_MS |
1000 |
执行完成后结果在表中保留多久(ms),供正在等待的并发实例读取 |
SINGLEFLIGHT_LOCK_TTL_MS |
30000 |
执行者持锁上限(ms),期间按 1/3 周期续租;执行者崩溃后到期可被接管 |
SINGLEFLIGHT_POLL_MS |
200 |
等待方轮询间隔(ms)。不建议低于 100:每次轮询都是一次对协调表的 SELECT,过密会显著消耗 D1 subrequest 配额与 CPU |
SINGLEFLIGHT_WAIT_MS |
15000 |
等待方最长等待(ms),超时后自行执行,避免被慢请求拖死 |
行为要点:
- 两级去重:进程内合并(所有模式都生效)+ 数据库表协调(
db模式,跨 isolate 生效)。 - 不做结果缓存:只有「到达时观察到执行者正在运行」的请求才会复用结果;新到达的请求 会回收旧记录并重新执行,因此不存在「删除文件后刷新仍看到旧文件」的脏读。
- 可用性优先:表不存在、数据库超时、结果无法序列化、执行者崩溃等协调层异常一律 降级为「各自执行一次」,业务不会失败;而业务函数自身的异常会原样抛出且不重试。
- 表结构:
x_singleflight由 SQL 驱动在初始化时自动创建,属运行时数据,不参与配置读写。 - 运行统计(
executed/coalesced/shared/fallback)可在/api/debug/info的singleflight字段查看,用于确认跨实例协调是否真的生效。
详细配置说明请参考 官方文档
在使用过程中遇到问题,可通过以下渠道获取帮助:
- 🐛 提交 Bug 或功能请求:请前往 Issues
- 💬 一般性问题与交流:请前往 Discussions 讨论区
OpenList 是基于 AGPL-3.0 许可证的开源软件。
🌐 @GitHub ·
感谢以下项目及其贡献者: