如何在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
相关产品推荐
相关产品推荐

