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

如何使用ReactJS将AWS S3存储桶的多个文件打包为ZIP批量下载

React 实现多个S3文件打包ZIP下载方案

1. 前置依赖安装

我们需要两个第三方库完成浏览器端打包+下载触发能力,执行以下命令安装:

npm install jszip file-saver

2. 核心实现逻辑

  • 遍历你的文件数据结构,拿到每个文件的S3访问地址和文件名
  • 通过fetch请求获取每个文件的Blob二进制数据(注意S3桶需要配置CORS允许你的前端域名访问,否则会跨域失败)
  • 将所有Blob写入JSZip创建的压缩包实例中
  • 所有文件添加完成后生成ZIP包的二进制流,触发浏览器下载

3. 完整代码示例

import { useState } from 'react';
import JSZip from 'jszip';
import { saveAs } from 'file-saver';

// 你的文件数据结构
const FILE_DATA = {
  item1: {
    name: "dummy.pdf",
    relativeUrl: "b9dde810-4935-4471-a22d-bdaf61e8bd62dummy.pdf",
    url: "https://upaged-file-store-prod.s3.ap-southeast-2.amazonaws.com/b9dde810-4935-4471-a22d-bdaf61e8bd62dummy.pdf?AWSAccessKeyId=AKIAVRO4YTL2YDUPVPPW&Expires=1625413917&Signature=z1DacLIOltfmFJbpt7AEy%2BeoK0s%3D"
  },
  item2: {
    name: "Sell the Solution, Not the Product..png",
    relativeUrl: "6397c507-0d05-4cd7-8e4b-371249f72dbeSell the Solution, Not the Product..png",
    url: "https://upaged-file-store-prod.s3.ap-southeast-2.amazonaws.com/6397c507-0d05-4cd7-8e4b-371249f72dbeSell%20the%20Solution%2C%20Not%20the%20Product..png?AWSAccessKeyId=AKIAVRO4YTL2YDUPVPPW&Expires=1625413938&Signature=zkDHlWu9kv%2BXgOpRQToG%2Bpbyafk%3D"
  },
  item3: {
    name: "ales-nesetril-Im7lZjxeLhg-unsplash.jpg",
    relativeUrl: "2e07b606-d1a0-4587-b8bb-c8f4b3927483ales-nesetril-Im7lZjxeLhg-unsplash.jpg",
    url: "https://upaged-file-store-prod.s3.ap-southeast-2.amazonaws.com/2e07b606-d1a0-4587-b8bb-c8f4b3927483ales-nesetril-Im7lZjxeLhg-unsplash.jpg?AWSAccessKeyId=AKIAVRO4YTL2YDUPVPPW&Expires=1625413971&Signature=U0d4%2BAPwi6e41c%2BU542ydoj%2BGBk%3D"
  },
  item4: {
    name: "icons8-dashboard-layout-96.png",
    relativeUrl: "18b4312f-dd20-4c8f-89d3-bea024fb32b6icons8-dashboard-layout-96.png",
    url: "https://upaged-file-store-prod.s3.ap-southeast-2.amazonaws.com/18b4312f-dd20-4c8f-89d3-bea024fb32b6icons8-dashboard-layout-96.png?AWSAccessKeyId=AKIAVRO4YTL2YDUPVPPW&Expires=1625413996&Signature=9IXyDVvRKAAWcs2yR%2FChE4pj5Sc%3D"
  }
};

const ZipDownloadButton = () => {
  const [loading, setLoading] = useState(false);

  const downloadZip = async () => {
    setLoading(true);
    const zip = new JSZip();
    const fileList = Object.values(FILE_DATA);

    try {
      // 批量下载所有文件并写入zip
      const filePromises = fileList.map(async (file) => {
        const response = await fetch(file.url);
        if (!response.ok) throw new Error(`下载文件${file.name}失败`);
        const blob = await response.blob();
        // 文件名如果有重复可以自行加前缀处理,避免zip内文件覆盖
        zip.file(file.name, blob);
      });

      // 等待所有文件下载完成
      await Promise.all(filePromises);

      // 生成zip包
      const zipBlob = await zip.generateAsync({ type: 'blob' });

      // 触发下载
      saveAs(zipBlob, '附件打包.zip');
    } catch (err) {
      console.error('打包下载失败:', err);
      // 这里可以加你的错误提示逻辑,比如弹窗提示用户
    } finally {
      setLoading(false);
    }
  };

  return (
    <button onClick={downloadZip} disabled={loading}>
      {loading ? '打包中...' : '下载全部附件'}
    </button>
  );
};

export default ZipDownloadButton;

4. 可选优化点

  • 如果存在同名文件,写入zip时可以给文件名加随机后缀或者拼接ID,避免文件被覆盖
  • 大文件打包时可以给JSZip的generateAsync方法添加进度回调,显示打包进度
  • 如果文件数量过多或文件过大,建议改用后端打包方案,避免浏览器内存占用过高导致页面卡顿

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 02:27:02