本系列面向刚入行的后端开发者,结合当前工程的 Markdown ZIP 转 HTML 功能,介绍如何:
接收用户上传的 ZIP
→ 使用 yauzl 安全、流式读取
→ 找到 Markdown 和资源文件
→ 转换并清理 HTML
→ 使用 archiver 创建结果 ZIP
→ 通过 Express 返回下载
教程重点放在 yauzl。archiver 的 API 相对直观,但输出 HTTP 响应时仍要正确处理 Stream、错误和客户端中止。
yauzl
输入:已有 ZIP
输出:Entry 元数据和每个文件的 Readable Stream
archiver
输入:文件、目录、Buffer 或 Readable Stream
输出:正在生成的 ZIP Readable/Transform Stream
它们不是互相替代的库:
node:zlib 负责 gzip、Deflate、Brotli 等压缩算法和流,但不是完整的 ZIP 项目读取器;multipart/form-data,不会验证 ZIP 内部是否安全。yauzl 没有把核心 API 设计成一个简单的 extractAll()。典型流程是:
打开 ZipFile
→ readEntry()
→ 收到 entry 事件
→ 校验文件名、类型和大小
→ openReadStream()
→ pipeline 到受控目标
→ 当前 Entry 完成后再 readEntry()
多出来的步骤带来了控制能力:
用户上传的 ZIP 必须被视为不可信输入,包括:
Entry 文件名
压缩前后大小
目录层级
扩展名
文件内容
符号链接属性
Markdown 文本和最终 HTML
Multer 的 fileSize 只限制上传的 ZIP 文件本身,不能限制它解压后有多大。生产实现至少还需要限制:
本系列补充以下实现说明:
services/markdown-export/markdown-zip-export-implementation-guide.mdservices/markdown-export/markdown-zip-export-scaffold.md实现说明回答“当前功能准备怎样组织”;本系列回答“yauzl、archiver 和 Stream 为什么这样使用”。