【问题标题】:Upload image from URL to Google Drive through Google Drive API Javascript通过 Google Drive API Javascript 从 URL 上传图片到 Google Drive
【发布时间】:2020-08-20 07:55:31
【问题描述】:

我是 Javascript 新手,如果我的问题对你来说很蹩脚,我很抱歉。我想从我的网站上传一张图片到我的 Google Drive。我已经成功实现了身份验证和文件夹创建部分,但我对上传过程感到困惑。
假设这是我在 Google Drive 中创建文件夹的代码:

function createFolder(folderName) {
  var parentId = 'xxxxxxx';//some parentId of a folder under which to create the new folder
  var fileMetadata = {
    'name' : folderName,
    'mimeType' : 'application/vnd.google-apps.folder',
    'parents': [parentId]
  };
  gapi.client.drive.files.create({
    resource: fileMetadata,
  }).then(function(response) {
    switch(response.status){
      case 200:
      var file = response.result;
      console.log('Created Folder Id: ', file.id);
      uploadImage(file.id);
      break;
      default:
      console.log('Error creating the folder, '+response);
      break;
    }
  });
}

现在我想从这个 url 上传我的图片:https://xxxxxx.com 从上面的响应 (file.id) 到新创建的文件夹中

这是我在 Google API 文档中得到的,但我应该在哪里放置/附加我的网址?

function uploadImage(folderId) {
  var fileMetadata = {
    'name': 'photo.jpg',
    parents: [folderId]
  };
  var media = {
    mimeType: 'image/jpeg',
    body: fs.createReadStream('files/photo.jpg')
  };
  drive.files.create({
    resource: fileMetadata,
    media: media,
    fields: 'id'
  }, function (err, file) {
    if (err) {
      // Handle error
      console.error(err);
    } else {
      console.log('File Id: ', file.id);
    }
  });
}   

非常感谢。

【问题讨论】:

  • 看来你的上下脚本分别是Javascript和Node.js。不幸的是,我无法理解你的问题。我为此道歉。我可以问一下您当前问题的详细信息和您的目标吗?
  • @Tanaike 感谢您的评论。让我再解释一下我的问题。我在某个网址上有一张图片,比如 (example.com/something)。因此,我想使用 Google Drive API 将该图片从该网址上传到我的 Google Drive。我想将该图像保存/上传到一个特定的文件夹中,我也想从我的客户端创建该文件夹。所以在这里我在成功验证后在父文件夹下创建了该文件夹(帖子中我的代码部分的第一部分)。
  • 现在是时候将该 URL (example.com/something) 中的图像上传/保存到我的 Google Drive 中这个新创建的文件夹中了。但是当我在 Google API 官方文档中搜索时,我发现了这段代码(帖子中我的代码部分的第二部分),我不知道如何附加我的 url (example.com/something) 以便它可以上传到我的 Google 云端硬盘。
  • 所以在 Google API 的官方文档(我的代码的第二部分)中,我在 var fileMetadata 下看到了 name: photo.jpg,但我有 url 而不是任何图像名称。那么如何将我的网址附加到此功能,以便上传到我的 Google 云端硬盘。谢谢!
  • 看看我的答案,测试一下,然后告诉我你的结果

标签: javascript file-upload google-drive-api


【解决方案1】:

我相信你的目标如下。

  • 您想从 URL 下载文件并使用 Javascript 将下载的文件上传到 Google 云端硬盘。
  • 在您的情况下,您的 gapi.client 可用于将文件上传到 Google 云端硬盘。

修改点:

  • 不幸的是,在当前阶段,gapi.client.drive.files.create 似乎仍然无法发送包含内容的请求。 Ref 所以在这种情况下,我想建议使用fetch 作为解决方法。使用fetch时,可以使用multipart/form-data请求文件内容和元数据。
  • 在此解决方法中,访问令牌使用来自gapi.client。所以这个脚本假设你的gapi.client 可以用来上传文件。请注意这一点。

修改后的脚本:

const url = "###";  // Please set the URL.
const fileName = "sample filename";
const folderId = "###";  // Please set the folder ID.

fetch(url).then(res => res.blob()).then(blob => {
  const form = new FormData();
  form.append('metadata', new Blob([JSON.stringify({name: fileName, parents: [folderId]})], {type: 'application/json'}));
  form.append('file', blob);
  fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
    method: 'POST',
    headers: new Headers({'Authorization': 'Bearer ' + gapi.auth.getToken().access_token}),
    body: form
  }).then(res => res.json()).then(val => console.log(val));
});
  • 当您运行此脚本时,可以在控制台中看到以下结果。 (当 URL 为 Jpeg 图片文件的直接链接时。)

      {
        "kind": "drive#file",
        "id": "###",
        "name": "sample filename",
        "mimeType": "image/jpeg"
      }
    

注意:

  • 在这种情况下,使用uploadType=multipart。所以最大文件大小为 5 MB。请注意这一点。当您想使用超过 5 MB 时,请检查可恢复上传。 Ref

参考资料:

补充:

为了避免与 CORS 相关的错误,作为另一种方法,我想建议使用 Web Apps 作为包装器。在这种情况下,客户端是 Javascript。此 Javascript 可在 Google 之外使用。

用法:

请执行以下流程。

1。创建 Google Apps 脚本的新项目。

Web Apps 的示例脚本是 Google Apps 脚本。所以请创建一个 Google Apps Script 项目。

如果要直接创建,请访问https://script.new/。在这种情况下,如果您没有登录 Google,则会打开登录屏幕。所以请登录谷歌。这样,Google Apps Script 的脚本编辑器就打开了。

2。准备脚本。

请将以下脚本(Google Apps 脚本)复制并粘贴到脚本编辑器中。此脚本适用于 Web 应用程序。

服务器端:Google Apps 脚本

此脚本用于 Web 应用程序。在这种情况下,Web 应用程序被用作包装器。

function doGet(e) {
  const imageUrl = e.parameter.imageUrl;
  const res = UrlFetchApp.fetch(imageUrl);
  if (res.getResponseCode() != 200) throw new Error("Image couldn't be retrieved.");
  const blob = res.getBlob();
  const file = DriveApp.getFolderById(e.parameter.folderId).createFile(blob.setName(e.parameter.filename));
  const obj = {id: file.getId(), name: file.getName(), mimeType: file.getMimeType()};
  return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON);
}

3。部署 Web 应用程序。

  1. 在脚本编辑器上,通过“发布”->“部署为 Web 应用”打开一个对话框。
  2. “执行应用程序为:”选择“我”
    • 由此,脚本以所有者身份运行。
  3. “谁有权访问应用程序:”选择“任何人,甚至是匿名的”
  4. 单击“部署”按钮作为新的“项目版本”。
  5. 自动打开“需要授权”对话框。
    1. 点击“查看权限”。
    2. 选择自己的帐户。
    3. 点击“此应用未验证”中的“高级”。
    4. 点击“转到###项目名称###(不安全)”
    5. 点击“允许”按钮。
  6. 点击“确定”。
  7. 复制 Web 应用程序的 URL。就像https://script.google.com/macros/s/###/exec
    • 当您修改 Google Apps 脚本时,请重新部署为新版本。这样,修改后的脚本就会反映到 Web 应用程序中。请注意这一点。

4。将文件从客户端上传到服务器端。

客户端:HTML & Javascript

请将您的 Web 应用程序的 URL 设置为以下脚本。并且,请设置文件名和文件夹ID。

const imageUrl = "###"; // Please set the URL of image.

const url = "https://script.google.com/macros/s/###/exec"; // Please set the URL of Web Apps.
const qs = new URLSearchParams({
  imageUrl: imageUrl,
  filename: "sample filename",
  folderId: "###", // Please set folder ID.
});
fetch(`${url}?${qs}`).then((res) => res.json()).then(console.log).catch(console.log);
结果:

运行上述脚本时,将返回以下值。可以在控制台看到返回值。

{
  "id": "###",
  "name": "###",
  "mimeType": "###"
}

注意:

  • 当您修改 Web Apps 的脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。

参考资料:

【讨论】:

  • 我正在调查,先生。感谢您长期以来的支持和建议。我非常感谢。保持安全保持祝福! :)
  • @Avow Studio 感谢您的回复。我很高兴你的问题得到了解决。我愿意支持你。但是您的评论问题是新问题,这与您的问题不同。那么您可以通过包含详细信息将其作为新问题发布吗?因为当您的初始问题被评论更改时,看到您的问题的其他用户会感到困惑。通过将其发布为新问题,包括我在内的用户可以想到您的新问题。如果您能合作解决您的新问题,我很高兴。
  • @Avow Studio 感谢您的回复。当您发布包含更多信息的新问题时,我想检查一下。而且,它还能帮助其他用户思考解决方案。
  • 您好先生,我已经发布了我的问题。请看一看。谢谢! stackoverflow.com/questions/63555056/…
  • @Avow Studio 感谢您的回复。我会检查它。当我能找到修改点时,我想提出它作为答案。
【解决方案2】:

尝试使用此 sn-p 上传您的照片文件:

// download file from website 
const http  = require('https')
const fs    = require('fs')

let file    = fs.createWriteStream('Photo001.jpg')
let request = http.get(
    'https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_2x.png', 
    (response) => {
        response.pipe(file)
    })

// upload file to Google Drive
let fileMetadata = {
  'name'    : 'Photo001',
  'mimeType': 'image/jpeg'
}

let media = {
  mimeType  : 'image/jpeg',
  body      : fs.createReadStream('Photo001.jpeg')
}

function uploadFile(auth){

  const drive = google.drive({version: 'v3', auth})

  drive.files.create({
    resource: fileMetadata,
    media   : media,
    fields  : 'id'
  }, (err, res) => {
    if (err) return console.log('The API returned an error: ' + err)
  })

}

文档

【讨论】:

  • 感谢您的回复。但是我会在哪里附加我的图像 URL 的值呢?正如我所说的(example.com/something),这是我的图片 URL 链接,但在答案中,与此无关。我只能在fileMetadata 中看到name: photo001 参数。我应该如何传递 URL 参数?
  • 嗨@AvowStudio,我编辑了我的答案(添加了如何从网站下载文件),测试它并让我知道一切是否按预期工作
  • 感谢@Jeff Rush。你能告诉我我应该在这里放什么let file = fs.createWriteStream('Photo001.jpg'),因为我只有 URL 图片。和文件夹 ID,我想在其中上传该图像。
猜你喜欢
  • 1970-01-01
  • 2019-02-16
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
相关资源
最近更新 更多