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

从FastAPI服务器下载后.zip文件损坏问题求助

问题

通过FastAPI服务器下载使用Python shutil库创建的.zip文件时,前端console打印乱码,下载的文件损坏;含特殊字符的.txt文件也出现相同问题。

现有代码

1. 创建.zip文件的代码

shutil.make_archive(base_name = base_name , 
                      format = 'zip', 
                      root_dir = 'fileName.zip')

2. FastAPI路由方法

@app.get("/_archiveFiles_download", response_class = FileResponse)  
async def archiveFiles_download(request: Request):  
     archiveFilePath = 'fileName.zip'  
     return FileResponse(path = archiveFilePath)

3. JavaScript下载函数

// function to download archive file 
function downloadZipFiles() {  
    $.get("./archiveFiles_download").done(function (data) {  
        console.log(data)  // prints garbage in console window  
        // Create an anchor element for the download link  
       const link = document.createElement("a");  
       const blob = new Blob([data1], { type: "application/x-zip-compressed" });
       const url = URL.createObjectURL(blob); 
       link.href = url;
       link.download = 'fileName_Download.zip'; // Set the desired file name 
       link.click();         // Clean up the temporary URL 
       URL.revokeObjectURL(url);  
   });  
}

问题原因

  1. 前端使用$.get默认以文本格式解析二进制数据,导致zip/txt的二进制内容被错误转码,引发文件损坏、乱码
  2. shutil压缩代码参数错误:root_dir应传入要压缩的源目录路径,而非目标zip文件名
  3. FastAPI响应未明确设置编码和正确的Content-Disposition头,导致特殊字符处理异常

修复方案

1. 修正shutil压缩逻辑

root_dir指定要压缩的源目录,base_name为生成的zip文件名前缀(无需带.zip后缀,函数会自动添加):

import shutil

# 示例:压缩"target_dir"目录,生成"fileName.zip"
base_name = "fileName"
shutil.make_archive(
    base_name=base_name,
    format='zip',
    root_dir='target_dir'  # 改为要压缩的源目录路径
)

2. 优化FastAPI路由

添加文件存在检查,设置正确的媒体类型、编码和下载文件名:

from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import FileResponse
import os
import urllib.parse

app = FastAPI()

@app.get("/_archiveFiles_download", response_class=FileResponse)  
async def archiveFiles_download(request: Request):  
    archiveFilePath = 'fileName.zip'  
    if not os.path.exists(archiveFilePath):
        raise HTTPException(status_code=404, detail="文件不存在")
    
    # zip文件用application/zip;txt文件改为text/plain; charset=utf-8
    return FileResponse(
        path=archiveFilePath,
        filename="fileName_Download.zip",
        media_type="application/zip",
        headers={
            # 支持UTF-8文件名,解决特殊字符显示问题
            "Content-Disposition": f"attachment; filename*=UTF-8''{urllib.parse.quote('fileName_Download.zip')}"
        }
    )

3. 修复前端下载逻辑

改用支持二进制数据的请求方式,指定responseType: 'blob':

方案一:使用Fetch API

function downloadZipFiles() {
    fetch("./_archiveFiles_download")
        .then(response => {
            if (!response.ok) throw new Error("下载请求失败");
            return response.blob();
        })
        .then(blob => {
            const link = document.createElement("a");
            const url = URL.createObjectURL(blob);
            link.href = url;
            link.download = 'fileName_Download.zip';
            link.click();
            URL.revokeObjectURL(url);
        })
        .catch(err => console.error("下载出错:", err));
}

方案二:使用jQuery Ajax

function downloadZipFiles() {
    $.ajax({
        url: "./_archiveFiles_download",
        method: "GET",
        xhrFields: {
            responseType: 'blob'  // 明确获取二进制Blob数据
        },
        success: function(blob) {
            const link = document.createElement("a");
            const url = URL.createObjectURL(blob);
            link.href = url;
            link.download = 'fileName_Download.zip';
            link.click();
            URL.revokeObjectURL(url);
        },
        error: function(err) {
            console.error("下载失败:", err);
        }
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:17:41