Google Drive API 进度条错误

2024-02-24

我编写了以下代码来将文件上传到我的 Google 云端硬盘帐户。它工作得很好。然后我尝试添加一些上传进度跟踪器,但遇到了一些问题。它可以工作,但进度几乎立即达到 100%,远远早于上传完成。

export async function uploadFile(auth) {
  const fileMetadata = {
    name: FILENAME,
  };
  const fileWrite = fs.createReadStream(path.join(homedir(), 'Pictures', FILENAME));
  const fileSize = fs.statSync(path.join(homedir(), 'Pictures', FILENAME)).size;
  const media = {
    mimeType: FILETYPE,
    body: fileWrite,
  };
  const drive = google.drive({ version: 'v3', auth });
  const res = await drive.files.create({
    fileMetadata,
    media,
    fields: 'id',
  }, {
    onUploadProgress: (evt) => {
      const progress = (evt.bytesRead / fileSize) * 100;
      console.log(progress);
    },
  });
  console.log(res.data);
}

它上传我想要的文件,显示进度并返回文件 ID。问题是上传进度不对。我尝试上传一个 100mb 的文件,在 20mbps 的上传连接下,只花了 1.8 秒就完成了进度。 14 秒后承诺文件上传解决


新答案(此处修复了旧答案问题)

该问题可能是由于 Axios 未正确处理读取流引起的。您应该将读取流通过管道传输到 PassThrough 流并将其提供给 axios.put(),而不是将读取流直接传递给 axios.put()。

import axios from 'axios';
import { google } from 'googleapis';
import fs from 'fs';
import path from 'path';
import { PassThrough } from 'stream';

export async function uploadFile(auth) {
  const fileMetadata = {
    name: FILENAME,
  };
  const filePath = path.join(homedir(), 'Pictures', FILENAME);
  const fileSize = fs.statSync(filePath).size;
  const media = {
    mimeType: FILETYPE,
  };

  const drive = google.drive({ version: 'v3', auth });
  try {
    const uploadUrlRes = await drive.files.create({
      requestBody: fileMetadata,
      media: media,
      fields: 'id',
      uploadType: 'resumable',
    });

    const uploadUrl = uploadUrlRes.data;
    const fileWrite = fs.createReadStream(filePath);
    const passThrough = new PassThrough();
    fileWrite.pipe(passThrough);

    const axiosConfig = {
      headers: {
        'Content-Type': media.mimeType,
        'Content-Length': fileSize,
      },
      onUploadProgress: (evt) => {
        const progress = Math.round((evt.loaded / fileSize) * 100);
        console.log(progress);
      },
    };

    const res = await axios.put(uploadUrl, passThrough, axiosConfig);
    console.log(res.data);
  } catch (error) {
    console.error('Error uploading file:', error);
  }
}

旧答案。

使用 Axios 处理上传及其进度。首先,通过调用drive.files.create(),并将uploadType 参数设置为“可恢复”,使用Google Drive API 创建可恢复上传会话。这将返回一个可恢复会话 URI,可与 Axios 一起使用来上传文件。

现在,使用适当的标头和 onUploadProgress 事件处理程序配置 Axios。然后,我们使用 axios.put() 方法将文件上传到可恢复会话 URI。

import axios from 'axios';
import { google } from 'googleapis';
import fs from 'fs';
import path from 'path';

export async function uploadFile(auth) {
  const fileMetadata = {
    name: FILENAME,
  };
  const fileWrite = fs.createReadStream(path.join(homedir(), 'Pictures', FILENAME));
  const fileSize = fs.statSync(path.join(homedir(), 'Pictures', FILENAME)).size;
  const media = {
    mimeType: FILETYPE,
    body: fileWrite,
  };

  const drive = google.drive({ version: 'v3', auth });
  try {
    const uploadUrlRes = await drive.files.create({
      requestBody: fileMetadata,
      media: media,
      fields: 'id',
      uploadType: 'resumable'
    });

    const uploadUrl = uploadUrlRes.data;
    const axiosConfig = {
      headers: {
        'Content-Type': media.mimeType,
        'Content-Length': fileSize,
      },
      onUploadProgress: (evt) => {
        const progress = Math.round((evt.loaded / fileSize) * 100);
        console.log(progress);
      },
    };

    const res = await axios.put(uploadUrl, fileWrite, axiosConfig);
    console.log(res.data);
  } catch (error) {
    console.error('Error uploading file:', error);
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google Drive API 进度条错误 的相关文章

随机推荐