Загрузить изображение с URL-адреса на Google Диск через Google Drive API Javascript

Aug 18 2020

Я новичок в Javascript и извиняюсь, если мой вопрос кажется вам неуместным. Я хочу загрузить изображение со своего веб-сайта на свой Google Диск. Я успешно реализовал часть проверки подлинности и создания папки, но меня не смущает процесс загрузки.
Скажем, это мой код для создания папки на Google Диске:

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, но где мне разместить / прикрепить в ней свой URL?

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);
    }
  });
}   

Заранее большое спасибо.

Ответы

1 Tanaike Aug 19 2020 at 08:26

Я считаю вашей целью следующее.

  • Вы хотите загрузить файл по URL-адресу и загрузить загруженный файл на Google Диск с помощью Javascript.
  • В вашем случае вы gapi.clientможете использовать его для загрузки файла на Google Диск.

Пункты модификации:

  • На текущем этапе, к сожалению, кажется, что gapi.client.drive.files.createеще не удается отправить запрос, включая контент. Ссылка Итак, в этом случае я хотел бы предложить использовать 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 МБ. Пожалуйста, будьте осторожны. Если вы хотите использовать более 5 МБ, установите флажок «Возобновляемая загрузка». Ссылка

Рекомендации:

  • Использование Fetch
  • Загрузить данные файла

Добавлено:

Чтобы избежать ошибки, связанной с CORS, в качестве другого метода я хотел бы предложить использовать веб-приложения в качестве оболочки. В этом случае клиентская сторона - это Javascript. Этот Javascript можно использовать за пределами Google.

Применение:

Пожалуйста, сделайте следующий поток.

1. Создайте новый проект скрипта Google Apps.

Пример сценария веб-приложений - это сценарий Google Apps. Поэтому создайте проект скрипта Google Apps.

Если вы хотите создать его напрямую, перейдите к https://script.new/. В этом случае, если вы не вошли в систему Google, откроется экран входа в систему. Пожалуйста, войдите в Google. При этом открывается редактор сценариев Google Apps Script.

2. Подготовить сценарий.

Скопируйте и вставьте следующий скрипт (скрипт Google Apps) в редактор скриптов. Этот сценарий предназначен для веб-приложений.

На стороне сервера: скрипт Google Apps

Этот сценарий используется для веб-приложений. В этом случае веб-приложения используются в качестве оболочки.

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. Разверните веб-приложения.

  1. В редакторе скриптов откройте диалоговое окно, выбрав «Опубликовать» -> «Развернуть как веб-приложение».
  2. Выберите «Я» для «Запустить приложение как:» .
    • Таким образом, сценарий запускается от имени владельца.
  3. Выберите «Любой, даже анонимный» для «У кого есть доступ к приложению:» .
  4. Нажмите кнопку «Развернуть» как новую «версию проекта».
  5. Автоматически открыть диалоговое окно «Требуется авторизация».
    1. Щелкните «Просмотр разрешений».
    2. Выберите собственную учетную запись.
    3. Нажмите «Дополнительно» в разделе «Это приложение не проверено».
    4. Нажмите "Перейти к ### имени проекта ### (небезопасно)"
    5. Нажмите кнопку «Разрешить».
  6. Щелкните "ОК".
  7. Скопируйте URL-адрес веб-приложений. Это как https://script.google.com/macros/s/###/exec.
    • После изменения скрипта Google Apps повторно разверните его как новую версию. Таким образом, измененный сценарий отражается в веб-приложениях. Пожалуйста, будьте осторожны.

4. Загрузите файл со стороны клиента на сервер.

Клиентская сторона: HTML и Javascript

Установите URL-адрес ваших веб-приложений на следующий сценарий. И, пожалуйста, установите имя файла и идентификатор папки.

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": "###"
}

Заметка:

  • Когда вы изменили скрипт веб-приложений, повторно разверните веб-приложения как новую версию. Таким образом, последний сценарий отражается в веб-приложениях. Пожалуйста, будьте осторожны.

Рекомендации:

  • Веб-приложения
  • Использование преимуществ веб-приложений с помощью скрипта Google Apps
1 JeffRush Aug 18 2020 at 21:23

Попробуйте загрузить файл фотографии с помощью этого фрагмента:

// 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)
  })

}

Документация

  • Файлы: создать