使用Axios上传文件时出现「上传文件为空」错误
问题分析与解决方案
核心问题1:Google Drive下载未等待文件写入完成
你的getDriveFile函数中,await drive.files.get仅完成了请求发起,但流的pipe操作是异步的,此时文件还没完全写入磁盘就返回了filePath。后续上传时文件可能处于未写完状态,导致接口判定为空文件。
修复下载函数:
将流的写入操作封装为Promise,确保文件完全写入后再返回路径:
async function getDriveFile(auth, fileName, folderId) { const drive = google.drive({ version: 'v3', auth }); // 递归查找文件逻辑保持不变 async function findFileInFolder(folderId) { const res = await drive.files.list({ q: `name='${fileName}' and '${folderId}' in parents and trashed=false`, fields: 'files(id, name, mimeType)', }); if (res.data.files.length > 0) { return res.data.files[0]; } const subfolders = await drive.files.list({ q: `'${folderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`, fields: 'files(id, name)', }); for (const folder of subfolders.data.files) { const foundFile = await findFileInFolder(folder.id); if (foundFile) { return foundFile; } } return null; } const file = await findFileInFolder(folderId); if (!file) { throw new Error(`File not found: ${fileName}`); } const filePath = path.join('/tmp/', file.name.toLowerCase()); const dest = fs.createWriteStream(filePath); // 将流写入封装为Promise,确保文件写完再返回 await new Promise((resolve, reject) => { drive.files.get( { fileId: file.id, alt: 'media' }, { responseType: 'stream' }, (err, res) => { if (err) { reject(err); return; } res.data.pipe(dest); // 监听流完成和错误事件 dest.on('finish', resolve); dest.on('error', reject); } ); }); return filePath; }
核心问题2:Axios上传未以正确格式提交文件
Postman默认会将文件封装为multipart/form-data格式,但你的代码直接将文件流作为POST body发送,接口无法识别正确的文件数据,导致判定为空。
修复上传函数:
使用FormData包装文件流,并配置Axios的正确headers:
const FormData = require('form-data'); // 先执行npm install form-data安装依赖 async function uploadMediaToSermonAudio(URL, filePath) { console.log('File Path: ', filePath); const fileStream = fs.createReadStream(filePath); // 创建FormData并添加文件,字段名需和接口要求一致 const formData = new FormData(); formData.append('file', fileStream); const response = await axios.post(URL, formData, { headers: { ...formData.getHeaders(), // 自动生成multipart/form-data格式的headers }, maxContentLength: Infinity, // 处理90MB大文件需解除长度限制 maxBodyLength: Infinity }); if (response.status === 201) { console.log('Media uploaded!'); const data = response.data; console.log('Data: ', data); return true; } else { console.error('Media not uploaded:', response.statusText); return false; } }
额外注意事项
- 确认接口要求的文件字段名(比如
formData.append('file', ...)中的file是否匹配接口文档) - 大文件上传时,必须设置
maxContentLength和maxBodyLength为Infinity,避免Axios因默认长度限制中断请求
内容的提问来源于stack exchange,提问作者Alun Lewis
相关产品推荐
相关产品推荐

