【问题标题】:Update file to change mime type results in "Invalid MIME type provided for the uploaded content"更新文件以更改 MIME 类型导致“为上传的内容提供的 MIME 类型无效”
【发布时间】:2021-07-19 00:35:58
【问题描述】:

问题

我在 Google 云端硬盘上有一个文件,该文件是使用 Google 云端硬盘 api v3 上传的。 有问题的文件在上传时未转换为 Google 表格。 (是的,我的代码搞砸了,正在尝试修复它。)

它是用text/csv的mime类型上传的,下图显示它的类型为Comma separated values

我有另一个文件以正确的 mime 类型 application/vnd.google-apps.spreadsheet 上传,这导致该文件被转换为 Google 表格。下图显示其类型为Google sheet

更新文件并修复它。

我要做的是对使用错误 mime 类型上传的文件运行 file.update,然后更改其 mime 类型并再次上传文件,从而将其转换为 Google 表格。

将以下内容作为文件的元数据发送应该会导致它被转换。

 'mimeType': 'application/vnd.google-apps.spreadsheet' 

不幸的是它不会导致以下错误

错误:[ { 域:'全球', 原因:'invalidContentType', message: '为上传的内容提供的 MIME 类型无效。', 位置类型:'其他', 位置:'media.mimeType' }

我的代码

const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');

// npm install googleapis
// https://developers.google.com/drive/api/v3/quickstart/nodejs

// Desktop app credentials from Google Cloud console.
const KEYFILEPATH = 'C:\\Youtube\\dev\\ServiceAccountCred.json';

const FILEIDTOUPDATE = '1YtJxL1WptkHUbDHNWpcbKwcRs7rPo_cY';

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/drive'];

// Create a service account initialize with the service account key file and scope needed
const auth = new google.auth.GoogleAuth({
    keyFile: KEYFILEPATH,
    scopes: SCOPES
});

/**
 * Creates a new file on google drive and uploads it.
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
async function createAndUploadFile(auth) {

    const driveService = google.drive({version: 'v3', auth});
    let fileMetadata = {
        'name': 'sheet',
        'mimeType': 'application/vnd.google-apps.spreadsheet'   // will cause the file to be converted to the google drive type.
    };
    let media = {
        mimeType: 'text/csv',
        body: fs.createReadStream('sheet.csv')
    };
    await driveService.files.update({
        fileId : FILEIDTOUPDATE,
        resource: fileMetadata,
        media: media,
        fields: 'id'
    }, function (err, file) {
        if (err) {
            // Handle error
            console.error(err);
        } else {
            console.log('File Id: ', file.data.id);
        }
    });
}

createAndUploadFile(auth).catch(console.error);

我尝试过的。

为了测试这实际上不是我的代码的问题,我针对已正确上传的工作表运行了代码,并且工作正常。根据文档 MimeType 应该是可写的

我无法解释这个问题。我想知道 update 方法是否没有 create 方法的隐蔽超能力。

【问题讨论】:

  • 感谢您的回复。我带来的不便表示歉意。从您对While I understand your workaround, the documentation states mine type is write able so I should be able to update it. I already know about the copy method I am trying to use the update method.的回复中,我了解到我的回答对您的情况没有用处。我为我糟糕的技术深表歉意。所以我想删除我的答案。
  • @Tanaike 我希望你不要删除它,因为我确实认为它作为一种变通方法很有用。我将联系驱动团队中的某个人,看看这是否是文档中的错误。
  • 感谢您的回复。从您的回复中,我重新打开了我的答案。如果这有用,我很高兴。

标签: node.js google-api google-drive-api service-accounts google-api-nodejs-client


【解决方案1】:

关于'Invalid MIME type provided for the uploaded content.

  • Drive API 的“Files:update”方法更新文件而不改变文件ID。
  • 文件 ID 取决于 mimeType。
    • 例如,在您的情况下,Google Docs 文件的文件 ID 的长度与 CSV 文件的文件 ID 不同。

考虑到您的情况,您似乎正在尝试使用 Drive API 的“文件:更新”方法将 CSV 文件的 mimeType 更改为 Google 电子表格。如果可以使用“Files:update”方法更改mimeType,那么从上述情况来看,文件ID 也需要更改。我猜这种情况可能是当前问题的原因。

为了验证这个假设,我做了以下实验。

实验:

  • 当通过更改text/csv 的mimeType 的CSV 文件更新PNG 文件时,在不更改文件ID 的情况下将PNG 文件转换为CSV 文件。
  • 可以使用 PNG 数据将 CSV 文件转换为 PNG 文件,而无需更改文件 ID。
  • 如果不更改文件内容,CSV 文件的 mimeType 无法转换为image/png
    • 为了更改 mimeType,似乎可能需要使用数据。
  • 当 mimeType 没有改变,而 Spreadsheet 通过 CSV 文件更新时,可以实现。
  • 当请求正文包括将 mimeType 从 Spreadsheet 更改为 CSV 并且电子表格由 CSV 文件更新时,电子表格由 CSV 数据更新,而不更改 mimeType。
  • 当请求正文包括将 mimeType 从 CSV 更改为电子表格并且 CSV 文件由 CSV 文件更新时,会出现您的问题中的错误。
  • CSV 文件由 Google 电子表格更新,无法实现。因为无法检索 Google 文档文件。

根据以上结果,考虑如下情况。

  • 认为当用“Files:update”更新文件时,当文件ID没有因为mimeType的改变而改变时,可以做到这一点。
    • 例如,CSV 到 PNG,PNG 到 CSV。
  • 认为当用“Files:update”更新文件时,当文件ID因mimeType的改变而改变时,这是无法实现的。
    • 例如,CSV 到 Google 电子表格,Google 电子表格到 CSV。
  • 为了更改 mimeType,似乎可能需要使用数据。
    • 在我的实验中,至少需要使用 0 字节的 media 来更改 mimeType。

此外,上述结果可能能够回答“文件:更新”的 mimeType 的“可写”。

修改脚本:

关于你的脚本,例如CSV文件的mimeType转换为Google Spreadsheet时,可以使用Drive API的“Files:copy”的方法。在这种情况下,转换文件(电子表格)的文件 ID 从 CSV 文件更改。因此,我认为您的脚本可能可以进行如下修改。

const driveService = google.drive({ version: 'v3', auth });
let fileMetadata = { name: 'sheet' };
let media = {
  mimeType: 'text/csv',
  body: fs.createReadStream('sheet.csv'),
};
driveService.files.update(
  {
    fileId: FILEIDTOUPDATE,
    resource: fileMetadata,
    media: media,
    fields: 'id',
  },
  function (err, file) {
    if (err) {
      // Handle error
      console.error(err);
    } else {
      console.log('File Id: ', file.data.id);
      driveService.files.copy(
        {
          fileId: FILEIDTOUPDATE,
          resource: { mimeType: "application/vnd.google-apps.spreadsheet" },
        },
        function (err, { data }) {
          if (err) {
            console.error(err);
            return;
          }
          console.log(data);
        }
      );
    }
  }
);
  • 在上面修改的脚本中,FILEIDTOUPDATE 的 CSV 文件被sheet.csv 的文件使用“文件:更新”的方法更新。并且,使用“文件:复制”的方法将 CSV 文件转换为 Google 电子表格。
  • 如果您不需要离开 CSV 文件,您可以在“文件:复制”方法完成后删除 CSV 文件。

参考资料:

【讨论】:

  • 虽然我了解您的解决方法,但文档说明我的类型是可写的,因此我应该能够更新它。我已经知道我正在尝试使用更新方法的复制方法。
  • @DaImTo 感谢您的回复。我带来的不便表示歉意。从您对While I understand your workaround, the documentation states mine type is write able so I should be able to update it. I already know about the copy method I am trying to use the update method.的回复中,我了解到我的回答对您的情况没有用处。我为我糟糕的技术深表歉意。所以我想删除我的答案。
  • 我认为您的答案符合其需要,您正在验证 mime 类型可能无法实际写入并描述其原因。
  • @DaImTo 感谢您的回复。我很荣幸。
猜你喜欢
  • 1970-01-01
  • 2012-07-18
  • 2015-03-10
  • 2023-03-06
  • 2010-11-30
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
相关资源
最近更新 更多