Node.js Express文件下载后损坏(大小均为16字节)求助
文件下载功能异常排查与解决
问题描述
使用Node.js Express实现的文件下载功能出现异常,下载得到的文件大小固定为16字节且已损坏。无法确定是否为客户端问题,提供服务端、客户端代码寻求排查与解决方案。
服务端代码
import path from 'path' import fs from 'fs' import { fileURLToPath } from 'url' class authController { downloadFile(req, res) { console.log(req.query) try { const parentFolder = req.query.parentFolder const folderId = req.query.folderId const fileName = req.query.fileName const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const file = path.join(__dirname, `../files/${parentFolder}/${folderId}/${fileName}`) res.download(file, fileName) } catch (e) { console.log(e) res.status(500).json({ message: 'Something went wrong, please try again' }) } } } export default new authController()
客户端代码
onClick={async function (e) { e.stopPropagation() const request = 'downloadFile' const response = await fetch(`/api/auth/${request}?parentFolder=${parentFolder}&folderId=${folderId}&fileName=${item}`, { headers: { Authorization: 'Bearer ' + auth.token, }, }) if (response.status === 200) { console.log(response) const blob = response.blob() const downloadUrl = window.URL.createObjectURL(new Blob([blob], { type: 'image/png' })) const link = document.createElement('a') link.href = downloadUrl link.download = item document.body.appendChild(link) link.click() link.remove() } }}
问题排查与解决
核心问题定位
客户端代码中response.blob()是异步方法,未添加await关键字,导致blob变量实际是一个Promise对象而非真实的文件Blob数据。将Promise对象塞入新Blob中,生成的文件仅包含Promise的序列化内容,因此大小固定为16字节且文件损坏。
修复步骤
- 修正异步方法调用:将
const blob = response.blob()改为const blob = await response.blob(),等待异步操作完成后获取真实的Blob数据。 - 移除强制指定的文件类型:建议删除
{ type: 'image/png' }配置,直接使用response.blob()返回的原始Blob类型,避免因强制指定类型导致文件格式不匹配。修改后的Blob创建代码为new Blob([blob])。
额外排查建议
- 验证服务端文件路径:在服务端打印
file变量,确认路径指向真实存在的文件,且文件权限正常。 - 直接测试服务端接口:在浏览器中直接访问下载接口URL,检查是否能正常下载文件,快速排除服务端问题。
- 处理文件名特殊字符:若文件名包含特殊字符,需在服务端和客户端分别进行URL编码/解码,避免路径解析错误。
内容的提问来源于stack exchange,提问作者Vladimir Melnikov
相关产品推荐
相关产品推荐

