Dale Zak
Dale Zak

Reputation: 1135

Problem Posting Images To Google Drive API V3

I'm having problems posting images to https://www.googleapis.com/upload/drive/v3/files?uploadType=media. The file is created on my Google Drive, however the jpeg is always 35KB is size, so appears none of the image content ever gets uploaded.

Originally I thought it was bug in vue-google-api however now suspect it's something with the Google Drive API V3. When I try posting an image directly to the API, I experience the same problem.

Request

POST https://www.googleapis.com/upload/drive/v3/files?uploadType=media
Accept: */*
Accept-Encoding: gzip, deflate
Content-Type: image/jpeg
Content-Length: 26837
Accept-Language: en-ca
Authorization: Bearer ya29.Gl1pB5BN9khs33ygA9pnIbyxJYp87teqDUfm55EsEHmmPJz0...

/9j/4AAQSkZJRgABAQEASABIAAD//gAMQXBwbGVNYXJrCv/bAIQABwUFBgUFBwYGBggHBwgKEQs...

Response

HTTP/1.1 200 OK

Server: UploadServer
Content-Type: application/json; charset=UTF-8
X-GUploader-UploadID: AEnB2UrjBAKhEMI-rCdzXpfAF3rM3oBABNUVH9AnhFtoXsoRroYV3By4rVqEuU1mn_5rJ2u_msN99Z1m2r-6Lh53fAowxmQ7QGAgWr2bP6cEwfnfV9JE-Vc
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Vary: Origin, X-Origin
Date: Mon, 19 Aug 2019 17:04:18 GMT
Alt-Svc: quic=":443"; ma=2592000; v="46,43,39"
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 118
{
    "kind": "drive#file",
    "id": "16dC3Fv2vKIur426INggTZ6GzDvyRUPrV",
    "name": "Untitled",
    "mimeType": "image/jpeg"
}

Has anyone been able to successfully upload images to Google Drive API V3? Any idea what could be going wrong?

Upvotes: 1

Views: 1099

Answers (2)

poeticGeek
poeticGeek

Reputation: 1041

After many hours of hair pulling and viewing the same answers. The only thing that worked for me was to change from the multipart request (that Google documents) to using FormData.

Credit to this answer.

const metadata = JSON.stringify({
  name: myFile.name,
  mimeType: myFile.type,
});

const requestData = new FormData();

requestData.append("metadata", new Blob([metadata], {
  type: "application/json"
}));

requestData.append("file", items[0].file);

const xhr = new XMLHttpRequest();

xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");

const token = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;

xhr.setRequestHeader("Authorization", `Bearer ${token}`);

xhr.send(requestData);

Upvotes: 0

Tanaike
Tanaike

Reputation: 201378

How about this modification? About uploadType=media, the metadata cannot be included and I couldn't find the method that the base64 data is uploaded and converted. When I saw the link in your question, I noticed that you have tried 2 methods. One is uploadType=media. Another is uploadType=multipart. At the link, I also confirmed that both scripts don't work.

uploadType=multipart can upload the base64 data and convert it to the binary data. So here, I would like to propose the modification for uploadType=multipart.

Modification points:

I think that your request body is almost correct. But it is required to be modified a little.

  • In your question, you said that the data is converted to base64. In this case, Content-Transfer-Encoding is required to be set to the request body.
  • When the file is uploaded to Google Drive, even if Content-Length is not set, the file can be uploaded.

Modified script:

Please modify contentDisposition() as follows.

From:
body += "--" + boundary
     + "\r\nContent-Disposition: form-data; name=" + key
     + "\r\nContent-type: " + formData[key].type
     + "\r\n\r\n" + formData[key].value + "\r\n";
To:
body += "--" + boundary
     + "\r\nContent-Disposition: form-data; name=" + key
     + "\r\nContent-type: " + formData[key].type
     + (key == "file" ? "\r\nContent-Transfer-Encoding: base64" : "")  // Added
     + "\r\n\r\n" + formData[key].value + "\r\n";

And, please modify uploadGoogleMultipart() as follows.

From:
headers: {
    "Content-Type": "multipart/related; boundary=" + boundary,
    'Content-Length': body.length
},
To:
headers: {
    "Content-Type": "multipart/related; boundary=" + boundary,
},

Note:

  • In this modification, it supposes that you have already been able to upload the file to Google Drive using Drive API.

Reference:

If I misunderstood your question and this was not the direction you want, I apologize.

Upvotes: 2

Related Questions