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

React中POST API下载含文件Zip文件夹为空问题求助

问题分析与解决方案

核心问题点

  1. Axios请求配置错误:POST请求的请求体需用data字段,而非body(body是Fetch API的用法)
  2. JSZip用法错误:若API返回的是已打包好的Zip Blob,无需二次创建Zip并添加文件夹;若返回多文件数据,需正确遍历添加文件
  3. 状态与拼写问题:缺失buttonText状态定义,setCatergory拼写错误应为setCategory
  4. 缺失必要导入:未导入useState、Axios及UI组件

解决方案分两种场景

场景1:API返回已打包的Zip文件(Blob类型)

直接保存返回的Blob即可,无需JSZip二次处理:

import { useState } from "react";
import { saveAs } from "file-saver";
import Axios from "axios";
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';

// 替换为你的API基础地址
const baseUrl = "https://your-api-domain.com";

function Download({ apiToken }) {
  const [category, setCategory] = useState("");
  const [buttonText, setButtonText] = useState("Download");
  
  const handleClick = () => {
    setButtonText("Downloading...");
    
    const params = {
      subcategoryiid: category,
    };

    Axios({
      url: `${baseUrl}/cards/details`,
      method: "POST",
      responseType: "blob",
      headers: {
        Authorization: `Bearer ${apiToken}`,
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      // Axios使用data传递POST请求体
      data: params,
    })
      .then((res) => {
        // 直接保存API返回的Zip Blob
        saveAs(res.data, "project.zip");
        setButtonText("Download");
      })
      .catch((err) => {
        console.error(err);
        setButtonText("Download");
      });
  };

  return (
    <div>
      <TextField
        className="box"
        placeholder="enter facility code"
        required
        value={category}
        onChange={(e) => setCategory(e.target.value)}
      />
      <Button
        type="button"
        color="success"
        variant="contained"
        onClick={handleClick}
      >
        {buttonText}
      </Button>
    </div>
  );
}

export default Download;

场景2:API返回多文件原始数据(如文件数组)

假设API返回JSON格式的文件列表(包含文件名、类型、Base64内容),需用JSZip逐个添加文件再打包:

import { useState } from "react";
import { saveAs } from "file-saver";
import JSZip from "jszip";
import Axios from "axios";
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';

const baseUrl = "https://your-api-domain.com";

function Download({ apiToken }) {
  const [category, setCategory] = useState("");
  const [buttonText, setButtonText] = useState("Download");
  
  const handleClick = () => {
    setButtonText("Downloading...");
    
    const params = {
      subcategoryiid: category,
    };

    Axios({
      url: `${baseUrl}/cards/details`,
      method: "POST",
      headers: {
        Authorization: `Bearer ${apiToken}`,
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      data: params,
    })
      .then((res) => {
        const zip = new JSZip();
        // 假设res.data是文件数组,每个元素结构:{name: "文件名称", content: "Base64字符串"}
        res.data.forEach(file => {
          zip.file(file.name, file.content, { base64: true });
        });
        return zip.generateAsync({ type: "blob" });
      })
      .then((zipBlob) => {
        saveAs(zipBlob, "project.zip");
        setButtonText("Download");
      })
      .catch((err) => {
        console.error(err);
        setButtonText("Download");
      });
  };

  return (
    <div>
      <TextField
        className="box"
        placeholder="enter facility code"
        required
        value={category}
        onChange={(e) => setCategory(e.target.value)}
      />
      <Button
        type="button"
        color="success"
        variant="contained"
        onClick={handleClick}
      >
        {buttonText}
      </Button>
    </div>
  );
}

export default Download;

额外注意事项

  • 先确认API返回的具体格式:通过控制台查看res.data的类型和结构,选择对应场景的代码
  • 确保baseUrl配置正确,API请求能正常响应
  • 若使用Material-UI组件,需确保已正确导入TextField和Button

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:55:54