yauzl + archiver:Markdown ZIP 导入导出教程

本系列面向刚入行的后端开发者,结合当前工程的 Markdown ZIP 转 HTML 功能,介绍如何:

接收用户上传的 ZIP
  → 使用 yauzl 安全、流式读取
  → 找到 Markdown 和资源文件
  → 转换并清理 HTML
  → 使用 archiver 创建结果 ZIP
  → 通过 Express 返回下载

教程重点放在 yauzlarchiver 的 API 相对直观,但输出 HTTP 响应时仍要正确处理 Stream、错误和客户端中止。

学习路线

  1. 01 ZIP 工作流与基础概念
  2. 02 yauzl 核心 API
  3. 03 Entry、事件与文件流
  4. 04 安全读取与提取 ZIP
  5. 05 Markdown 工程导入与 HTML 转换
  6. 06 archiver 基础与 ZIP 输出
  7. 07 Express 5 集成
  8. 08 错误处理、清理与客户端中止
  9. 09 测试与生产检查清单

两个依赖的分工

yauzl
  输入:已有 ZIP
  输出:Entry 元数据和每个文件的 Readable Stream

archiver
  输入:文件、目录、Buffer 或 Readable Stream
  输出:正在生成的 ZIP Readable/Transform Stream

它们不是互相替代的库:

为什么 yauzl 看起来比 archiver 复杂

yauzl 没有把核心 API 设计成一个简单的 extractAll()。典型流程是:

打开 ZipFile
  → readEntry()
  → 收到 entry 事件
  → 校验文件名、类型和大小
  → openReadStream()
  → pipeline 到受控目标
  → 当前 Entry 完成后再 readEntry()

多出来的步骤带来了控制能力:

本系列始终坚持的安全边界

用户上传的 ZIP 必须被视为不可信输入,包括:

Entry 文件名
压缩前后大小
目录层级
扩展名
文件内容
符号链接属性
Markdown 文本和最终 HTML

Multer 的 fileSize 只限制上传的 ZIP 文件本身,不能限制它解压后有多大。生产实现至少还需要限制:

与当前工程的关系

本系列补充以下实现说明:

实现说明回答“当前功能准备怎样组织”;本系列回答“yauzl、archiver 和 Stream 为什么这样使用”。

官方参考