You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js中借助Archiver实现Zip归档文件下载?

在Next.js中通过Archiver生成Zip并作为响应返回

要将Archiver生成的Zip归档传递给NextResponse,核心是利用Node.js的PassThrough流桥接Archiver的输出和Next.js的响应流。以下是完整解决方案:

完整代码示例

import { PassThrough } from 'stream';
import Archiver from 'archiver';
import path from 'path';

export async function GET(request) {
  // 从请求中获取token(根据实际场景调整)
  const { searchParams } = new URL(request.url);
  const token = searchParams.get('token');

  // 使用绝对路径避免工作目录问题
  const filesPath = path.resolve(process.cwd(), 'data/files/');
  const archive = Archiver('zip', { zlib: { level: 9 } });
  const passThroughStream = new PassThrough();

  // 处理归档生成中的错误
  archive.on('error', (err) => {
    throw new Error(`归档生成失败: ${err.message}`);
  });

  // 将Archiver的输出导向PassThrough流
  archive.pipe(passThroughStream);

  // 添加文件到归档
  GetFilesFromKey(token).forEach((fileInfo) => {
    const fullFilePath = path.join(filesPath, token, fileInfo.filename);
    archive.file(fullFilePath, { name: fileInfo.filename });
  });

  // 完成归档生成
  archive.finalize();

  return new NextResponse(passThroughStream, {
    headers: {
      'Content-Disposition': `attachment; filename="files.zip"`,
      'Content-Type': 'application/zip',
      // 可选:设置内容长度,提升浏览器下载体验
      'Content-Length': archive.pointer().toString(),
    },
  });
}

关键说明

  • 流的桥接:PassThrough流作为中间层,接收Archiver的压缩输出并直接传递给NextResponse,避免将整个Zip文件加载到内存,适合大文件场景。
  • 路径处理:用path.resolve和path.join生成绝对路径,避免Next.js运行时工作目录变化导致的文件找不到问题。
  • 错误处理:必须监听Archiver的error事件,防止未处理的异常导致路由崩溃。
  • 响应头优化:application/zip比application/octet-stream更标准,能让浏览器正确识别文件类型;Content-Disposition确保触发下载行为而非直接打开。

内容的提问来源于stack exchange,提问作者Finn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:05:11