Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Last active March 20, 2024 04:21
  • Star 59 You must be signed in to star a gist
  • Fork 20 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save tanaikech/bd53b366aedef70e35a35f449c51eced to your computer and use it in GitHub Desktop.
Upload Files to Google Drive using Javascript

Upload Files to Google Drive using Javascript

News

At October 11, 2019, I published a Javascript library to to run the resumable upload for Google Drive. When this is used, the large file can be uploaded. You can also use this js library.

Description

This is a sample script for uploading files to Google Drive using Javascript. The files are uploaded by Drive API v3. gapi.client.drive.files.create() can create an empty file on Google Drive. But it cannot directly upload files including contents. I think that this might not be able to upload files and metadata with the multipart/related, although this might be resolved by the future update. So now, as one of workarounds, I use using XMLHttpRequest.

  • This sample uses gapi.
    • Before you use this, please enable Drive API at API console and carry out the installation of gapi.
  • When this script is run, a text file including "sample text" is created to Google Drive.
  • When you use this script, please set fileContent and metadata.

In this sample script, a text file including contents is created under a folder.

Sample script :

var fileContent = 'sample text'; // As a sample, upload a text file.
var file = new Blob([fileContent], {type: 'text/plain'});
var metadata = {
    'name': 'sampleName', // Filename at Google Drive
    'mimeType': 'text/plain', // mimeType at Google Drive
    'parents': ['### folder ID ###'], // Folder ID at Google Drive
};

var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
form.append('file', file);

var xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.responseType = 'json';
xhr.onload = () => {
    console.log(xhr.response.id); // Retrieve uploaded file ID.
};
xhr.send(form);

Request body :

In this script, form is as follows. This is sent to Google Drive using the create method of Drive API.

------WebKitFormBoundaryxX0XmxgooMjdUECR
Content-Disposition: form-data; name="metadata"; filename="blob"
Content-Type: application/json

{"name":"sampleName","mimeType":"text/plain","parents":["#####"]}
------WebKitFormBoundaryxX0XmxgooMjdUECR
Content-Disposition: form-data; name="file"; filename="blob"
Content-Type: text/plain

sample text
------WebKitFormBoundaryxX0XmxgooMjdUECR--

Sample script 2

When XMLHttpRequest is modified to fetch, the script becomes as follows.

var fileContent = 'sample text'; // As a sample, upload a text file.
var file = new Blob([fileContent], {type: 'text/plain'});
var metadata = {
    'name': 'sampleName', // Filename at Google Drive
    'mimeType': 'text/plain', // mimeType at Google Drive
    'parents': ['### folder ID ###'], // Folder ID at Google Drive
};

var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
form.append('file', file);

fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id', {
    method: 'POST',
    headers: new Headers({ 'Authorization': 'Bearer ' + accessToken }),
    body: form,
}).then((res) => {
    return res.json();
}).then(function(val) {
    console.log(val);
});

Testing:

  • January 11, 2022: When I tested this script, no error occurs. I could confirm that A text file including sample text as the filename of sampleName can be created to the specific folder.
@gsborisgithub
Copy link

'parents': ['### folder ID ###']
do you need to provide it?

@dmarshall83
Copy link

any idea how to get this to work with resumeable uploads

@SamuelMuloki
Copy link

This worked great for me thanks.

@tanaikech
Copy link
Author

You can see a sample about the resumable upload at https://github.com/tanaikech/Resumable_Upload_For_WebApps

@tanaikech
Copy link
Author

If you don't want to put the file to the specific folder, you can remove 'parents': ['### folder ID ###'],.

@tyzero
Copy link

tyzero commented Aug 9, 2019

Cool Man!

@tanaikech
Copy link
Author

Thank you!

@trantronghien
Copy link

Hi tannaukech, how to upload a file from input element to google drive? I tried to use javascript object file to upload, but i got a problem. I attach a picture about my problem below. I'm looking forward to hear from you soon. Thank you.
image

@sarangnx
Copy link

sarangnx commented Apr 7, 2020

Seems like you are converting the form object to string, I guess.

@itsmhuang
Copy link

Was able to get it to work but what do I do with the file ID that's returned? It doesn't match any part of the URL for the created file when I go to google drive and open it. I assume I have to call another endpoint to get an actual URL.

@itsmhuang
Copy link

figured it out for anyone interested. Add to the endpoint the fields param with value webViewLink. This tutorial has fields=id, but use fields=webViewLink instead or add to it and whatever other properties you're interested in the response. E.g. 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=webViewLink'

@nwaughachukwuma
Copy link

@tanaikech, please how do I get this to work on mobile. Currently, only on mobile, it uploads, returns a 200 and the file id, but I cannot find the file on Google Drive. However, it works fine on web without issues.

@nwaughachukwuma
Copy link

Hi @tanaikech, I have a situation where this works on the web but not on mobile. On mobile, the upload mechanism doesn't seem to detect the metadata and as such, the file does not have a name/title. Please see this question on stack overflow

@aznoisib
Copy link

just fields parent as 'root'

@nwaughachukwuma
Copy link

Ok thanks @aznoisib but I couldn't it to work. To be clear, do you mean to construct the metadata field as below?

 const metadata = {
     name: file.name, 
     title: file.name,
     mimeType: contentType,
     // parents: ["parent-folder-id"],
     parents: ['root'], // <--- correct?
   };

@fullstackdev427
Copy link

How can I upload files into shared drive ?
Is this related to OAuth scope or User type (External or Internal) ?

@usamar98
Copy link

var accessToken = gapi.auth.getToken().access_token;
i can get error in this line

@F46y
Copy link

F46y commented Dec 10, 2021

Thank you so much! After hours of trying around, this saved us!

@felixkrautschuk
Copy link

Is this guide still up to date? On our side it is always uploading a file with name "Untitled" and I have no idea why the file name is not set correctly.

@Laptop0485
Copy link

This code is still working.
Does anyone know how this code can be used to upload images instead of text files?
Thanks!

@GuiRitter
Copy link

Been searching for hours and this finally did it! Google's API reference does not make it clear that one needs a multipart upload to send data or even what a Files resource is (the link is in the upload page but not on the create page). Neither does it have examples on how to do things with REST alone and with browser Javascript (without Node.js). Thanks!

@tanaikech
Copy link
Author

Thank you so much for a lot of comments. I'm glad your issues were resolved.

@leozitor
Copy link

How can I upload files into shared drive ?
Is this related to OAuth scope or User type (External or Internal) ?

if you want to upload to a shared drive you need to pass the argument supportsAllDrives=true on the request
example
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?supportsAllDrives=true&uploadType=multipart&fields=id')
them pass the drive id or folder on the metadata parents: ["parent-folder-id"],
it should work

@AbhiJohnv
Copy link

There is a spelling mistake at the bottom. It is including not inluding

@tanaikech
Copy link
Author

@AbhiJohnv Thank you for your comment. It's done.

@prajwalqubited
Copy link

how can we upload image or docs file what should I pass in fileContent ?

@vsl-dev
Copy link

vsl-dev commented Jan 25, 2024

How we can make these files to share public?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment