Angular 2+ HTTP POST и GDrive API. Возобновляемая загрузка файла с именем

Я пытаюсь загрузить файлы на Google Диск в Angular 2. Пока я могу загружать файлы, но без title и они "без названия"

Вот код для этого:

gDriveUploader(file): Promise<any> {
let authToken = tokenHere;
const url = `https://www.googleapis.com/upload/drive/v2/files/`
    let formData:FormData = new FormData();
    formData.append('title', file, file.name);
    let headers = new Headers({
      'Authorization': 'Bearer ' + authToken
    });
    headers.append('Accept', file.type);
    let options = new RequestOptions ({ 
      headers: headers,
    });

    console.log('OPTIONS: ', options)

    return this.http.post(`${url}`, formData, options)
        .toPromise()
           .then(response => response.json())
           .catch(e=>console.log(e));
}

Я знаю, что для отправки метаданных с файлом я должен добавить эти метаданные в Request Тело и использование в multipart или же resumable Типы загрузки. Но здесь я столкнулся с проблемой после проблемы и просто не могу сделать это должным образом.

Я полностью запутался. Вот на одном из моих подходов resumable тип загрузки:

gDriveUploader(file): Promise<any> {
let authToken = token;
const url = `https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable`
    console.log('FILE TO UPLOAD: ', file)
    let formData:FormData = new FormData();
    formData.append('name', file, file.name);
    let headers = new Headers({
      'Authorization': 'Bearer ' + authToken,
      'Content-Type': 'application/json; charset=UTF-8', //if remove "Bad Content" Error
      //'Content-Length': file.size, not sure if this one right?
    });
    let options = new RequestOptions ({ 
      headers: headers,
    });

    return this.http.post(`${url}`, formData, options)
        .toPromise()
           .then(response => response.json())
           .catch(e=>console.log(e));
}

это не только два моих подхода...

Согласно Drive API для resumable загрузить:

POST https://www.googleapis.com/drive/v3/files?uploadType=resumable 

HTTP/1.1
Authorization: Bearer [YOUR_AUTH_TOKEN]
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: image/jpeg
X-Upload-Content-Length: 2000000

Что такое Content-Length: 38? это длина файла, и я могу просто использовать file.size?

С multipart Я не могу понять, как добавить эти разделители границ в запросе.

Я видел некоторые вопросы и ответы, которые multipart не были поддержаны Angular, но это было 1-2 года назад. А сейчас?

Можно ли как-нибудь использовать возобновляемую загрузку в GDrive с дополнительными метаданными файла, используя стандартные функции Angular?

1 ответ

Решение

Так. Немного больше исследований о том, как работает API. Я придумал следующее решение для возобновляемой загрузки файлов. Основная идея, что в первый раз мне нужно сделать запрос и "установить метаданные" для моего файла и получить ответ со ссылкой, куда загрузить файл. И эта ссылка пришла как одна из response header называется location,

Здесь полностью рабочий код. Просто пройдите File возражать против первой функции.

Я просто быстро сделал 2 функции для этого. Первый из них установит метаданные (просто имя) и вызовет вторую функцию, чтобы загрузить только двоичные данные.

gDriveUploader(file): Promise<any> {
  let authToken = token
  const url = `https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable`
      let headers = new Headers({
        'Authorization': 'Bearer ' + authToken,
        'Content-Type': 'application/json; charset=UTF-8',
      });
      let options = new RequestOptions ({ 
        headers: headers,
      });
      return this.http.post(`${url}`, {name: file.fullName}, options) //just set the name
          .toPromise()
            .then(response => this.gDriveUploadFile(file, response.headers.get('location'))) //call second function to upload `file` to proper URI from response
            .then(response => {
                let id = response.json().id //parse id of uploaded file
                let resp = {fileName: file.fullName, fileType: file.fileType, fileSize: file.size, fileId: id} //create an object with file file properties, if you need that
                return resp // return object back to function that called this service
            })
            .catch(e=>console.log(e));
  }

Вторая функция для загрузки данных:

gDriveUploadFile(file, url): Promise<any> { //file and url we got from first func
  let authToken = token
      let headers = new Headers({
        'Authorization': 'Bearer ' + authToken,
        'Content-Type': 'application/json; charset=UTF-8',
        'X-Upload-Content-Type': file.type
      });
      let options = new RequestOptions ({ 
        headers: headers,
      });
      return this.http.post(`${url}`, file, options) //call proper resumable upload endpoint and pass just file as body
          .toPromise()
  }

Возможно, решение не идеальное, пока я здесь не занимаюсь ошибками и не пользуюсь resumable такие функции, как загрузка по частям, просто загрузить файл сразу. Но, надеюсь, если кто-то еще застрял с загрузкой GDrive, можно получить представление.

Другие вопросы по тегам