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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:37:29