ReactJS+FastAPI下载动态文件名文件时文件损坏问题求助
问题原因分析
你遇到的文件损坏问题,核心原因是前端构造下载请求时错误截断了文件的路径信息,导致后端无法定位到正确的文件,最终返回的错误页面(如404响应)被当成文件内容下载,造成文件损坏。
具体来说:你的后端接口filename参数需要接收完整的文件路径(比如docs/report.pdf),但前端代码中通过filepath.split('%2F').pop()只提取了文件名的最后一部分(比如report.pdf),导致后端去查找data/files/{collection_name}/report.pdf,而实际文件在data/files/{collection_name}/docs/report.pdf,自然找不到正确文件。
解决方案
修改前端handleDownloadClick函数,保留完整的文件路径传给后端,同时仅提取文件名的最后一部分作为下载时的显示文件名:
const handleDownloadClick = async (e, filepath, collectionName) => { e.preventDefault(); // 解码得到完整的文件路径(包含子目录) const fullFilename = decodeURIComponent(filepath); // 提取用于保存的文件名(仅取路径最后一段) const downloadFilename = fullFilename.split('/').pop(); // 构造正确的请求URL,传入完整的文件路径作为filename参数 const url = `/download/?filename=${encodeURIComponent(fullFilename)}&collection_name=${encodeURIComponent(collectionName)}`; console.log(`Downloading file: ${downloadFilename}`); console.log(`Full file path: ${fullFilename}`); console.log(`Collection: ${collectionName}`); console.log(`URL: ${url}`); try { const response = await fetch(url); if (!response.ok) { throw new Error(`Network response was not ok: ${response.statusText}`); } const blob = await response.blob(); const downloadUrl = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = downloadUrl; // 使用提取的文件名作为下载时的显示名称 a.download = downloadFilename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(downloadUrl); } catch (error) { console.error('File download failed:', error); alert('File download failed.'); } };
验证逻辑
- 后端接口通过Swagger能正常下载,说明后端逻辑本身没问题,只要传入正确的
filename(含路径)就能返回正确文件。 - 修改后前端会把完整的文件路径传给后端,后端可以准确定位到文件,返回的二进制内容就是原文件,下载后不会损坏。
内容的提问来源于stack exchange,提问作者Kelo
相关产品推荐
相关产品推荐

