主题
File Viewer
高性能本地文件浏览器,基于 FastAPI + Jinja2,适合在服务器上快速搭建文档预览与分享服务。
功能特性
文件预览
| 类型 | 格式 | 预览方式 |
|---|---|---|
| Markdown | .md / .markdown | 服务端渲染(GitHub 风格样式 + TOC + 表格),带两级缓存 |
| 代码 / 文本 | 40+ 种扩展名(.py .js .go .yaml .txt .log 等) | highlight.js 语法高亮 |
| 图片 | 常见 image/* 格式 | 内嵌预览 |
.pdf | 浏览器原生 PDF 阅读器(iframe 内嵌) | |
| Word | .docx | 前端 mammoth.js 渲染为 HTML |
| Excel | .xls / .xlsx | 前端 SheetJS 渲染,支持多工作表标签切换 |
其他说明:
- 旧版
.doc二进制格式不支持在线预览,仅提供下载。 - Office 文件超过 30 MB、代码文件超过 5 MB 时仅提供下载,避免浏览器/服务端卡顿。
- 所有文件均支持「原始内容」查看与「下载」。
目录浏览
- 面包屑导航、返回上级
- 当前目录文件名即时搜索过滤
- 按类型区分的文件图标(Markdown / PDF / Word / Excel / 图片 / 代码)
- 响应式布局:小屏设备文件列表自动转为卡片样式
- 明亮 / 暗黑主题切换(记忆用户偏好,跟随系统主题)
文档上传
目录页点击「上传」按钮,支持多文件上传至当前目录:
- 允许格式:
.md.markdown.txt.pdf.doc.docx.xls.xlsx - 单文件上限:50 MB
- 安全校验:文件名取 basename、目标目录路径穿越检查、扩展名白名单
- 上传成功后自动刷新目录列表
缓存架构
为应对文档持续累增,采用多级缓存:
- Markdown 渲染两级缓存
- L1 内存 LRU:按总字节数预算淘汰(默认 64 MB),而非条数
- L2 磁盘缓存:
key = sha256(文件路径 + mtime + size),源文件变更后旧缓存自然失效,重启不丢;超出预算(默认 1 GB)按访问时间 LRU 清理
- 目录列表缓存:短 TTL(10 秒,最多 256 个目录),上传后自动失效
- 浏览器缓存:文件原始内容响应带
ETag+Cache-Control: private, max-age=300,过期后 304 重校验
快速开始
bash
# 创建虚拟环境并安装依赖
python -m venv .venv
.venv/bin/pip install -r requirements.txt
# 启动(服务当前目录)
.venv/bin/python serve.py
# 指定文档根目录、端口、认证
.venv/bin/python serve.py /path/to/docs --port 9000 --auth-user admin --auth-pass secret访问 http://<host>:9000/。
命令行参数
| 参数 | 默认值 | 说明 |
|---|---|---|
root | . | 要服务的根目录(位置参数) |
--host | 0.0.0.0 | 监听地址 |
-p / --port | 8000 | 监听端口 |
--hidden | 关闭 | 显示隐藏文件/目录 |
--auth-user | 无 | Basic Auth 用户名(与 --auth-pass 同时提供才启用) |
--auth-pass | 无 | Basic Auth 密码 |
--cache-mb | 64 | Markdown 渲染内存缓存预算(MB) |
--cache-disk-mb | 1024 | Markdown 渲染磁盘缓存预算(MB),0 表示禁用 |
--cache-dir | ~/.cache/file-viewer/markdown | 磁盘缓存目录 |
后台运行
bash
nohup .venv/bin/python serve.py /path/to/docs --host 0.0.0.0 --port 9000 \
>> file-viewer.log 2>&1 &
echo $! > .file-viewer.pid
# 停止
kill $(cat .file-viewer.pid)项目结构
file-viewer/
├── serve.py # 应用入口与全部服务端逻辑(路由、缓存、上传)
├── requirements.txt # Python 依赖
├── templates/
│ ├── base.html # 基础布局:主题切换、全局样式
│ ├── index.html # 目录列表页:搜索、上传
│ ├── view.html # 文件预览页:Markdown/代码/图片/PDF/Word/Excel
│ └── macros.html # 文件类型 SVG 图标
└── .venv/技术栈
- 服务端:FastAPI + Uvicorn(uvloop/httptools)+ Jinja2 + Python-Markdown
- 前端:Tailwind CSS(CDN)、highlight.js、github-markdown-css、mammoth.js(Word)、SheetJS(Excel),均通过 CDN 加载,无构建步骤
- 性能:GZip 中间件、
FileResponse流式传输(支持 Range)、大文件线程池读取、多级缓存
接口说明
| 路由 | 方法 | 说明 |
|---|---|---|
/、/{path} | GET | 目录列表或文件预览页 |
/{path}?raw=1 | GET | 文件原始内容(inline,带 ETag/缓存头) |
/{path}?download=1 | GET | 下载文件(attachment) |
/__upload__ | POST | 上传文件,表单字段:dir(目标目录相对路径)、files(多文件) |
上传响应示例:
json
{"saved": ["a.md"], "failed": ["b.sh: 不支持的文件类型"]}安全注意事项
- 所有路径经
check_path校验,禁止越出根目录;上传文件名取 basename,双重防目录穿越。 - 启用
--auth-user/--auth-pass后,包括上传在内的所有路由都要求 Basic Auth。 - ⚠️ 若服务暴露公网且未开启认证,任何人都可以浏览和上传文件,请务必配置认证或置于内网/反向代理之后。