2

I'm trying to upload a file from my local computer to Google Drive using Javascript. Therefore, I run a local web server (simpleHTTPServer in python), then I use an Ajax request to GET the file. In my understanding the response should be a binary stream. Then I try to upload this binary stream to Google Drive using multipart upload.

I have tried several versions found on the net but all of them failed. You can see three of them below. As a result a file appeared in Google Drive with the correct name but its content was only a text saying "Object Blob" or "Object Arraybuffer" when I used blob or arraybuffer as responseType or an empty file when using the responseText property with no responseType specified.

What am I doing wrong? Thank you in advance.

function uploadFile_multipart (foldername, filename) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", foldername + filename, false);
    xmlhttp.overrideMimeType('text\/plain; charset=x-user-defined');
    xmlhttp.send();
    if (xmlhttp.status == 200) {
        var contentType = xmlhttp.getResponseHeader('Content-Type');
        var contentLength = xmlhttp.getResponseHeader('Content-Length');
        var contentData = xmlhttp.responseText;
        const boundary = 'foo_bar_baz';
        var multipartRequestBody = '--' + boundary + '\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n' +
            '{ "name": "' + filename + '", "mimeType": "' + contentType + '" }\r\n\r\n--' + boundary +
            '\r\nContent-Type: ' + contentType + '\r\n\r\n' +
            contentData + '\r\n--' + boundary + '--';
        var request = gapi.client.request({
            'path': '/upload/drive/v3/files',
            'method': 'POST',
            'params': {'uploadType': 'multipart'},
            'headers': {'Content-Type': 'multipart/related; boundary=' + boundary, 'Content-Length': contentLength},
            'body': multipartRequestBody
        });
        request.execute(function(resp) { alert(resp); });
    }
}

Another:

function uploadFile_multipart (foldername, filename) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onload = function() {
            var contentType = xmlhttp.getResponseHeader('Content-Type');
            var contentLength = xmlhttp.getResponseHeader('Content-Length');
            var contentData = xmlhttp.response;
            const boundary = 'foo_bar_baz';
            var multipartRequestBody = '--' + boundary + '\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n' +
                '{ "name": "' + filename + '", "mimeType": "' + contentType + '" }\r\n\r\n--' + boundary +
                '\r\nContent-Type: ' + contentType + '\r\n\r\n' +
                contentData + '\r\n--' + boundary + '--';
            var request = gapi.client.request({
                'path': '/upload/drive/v3/files',
                'method': 'POST',
                'params': {'uploadType': 'multipart'},
                'headers': {'Content-Type': 'multipart/related; boundary=' + boundary, 'Content-Length': contentLength},
                'body': multipartRequestBody
            });
            request.execute(function(resp) { alert(resp); });
    }
    xmlhttp.open("GET", foldername + filename, true);
    xmlhttp.responseType = "blob";
    xmlhttp.send();
}

Yet another:

function uploadFile_multipart (foldername, filename) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onload = function() {
        var contentType = xmlhttp.getResponseHeader('Content-Type');
        var contentLength = xmlhttp.getResponseHeader('Content-Length');
        var contentData = new Uint8Array(xmlhttp.response);
        const boundary = 'foo_bar_baz';
        var multipartRequestBody = '--' + boundary + '\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n' +
            '{ "name": "' + filename + '", "mimeType": "' + contentType + '" }\r\n\r\n--' + boundary +
            '\r\nContent-Type: ' + contentType + '\r\n\r\n' +
            contentData + '\r\n--' + boundary + '--';
        var request = gapi.client.request({
            'path': '/upload/drive/v3/files',
            'method': 'POST',
            'params': {'uploadType': 'multipart'},
            'headers': {'Content-Type': 'multipart/related; boundary=' + boundary, 'Content-Length': contentLength},
            'body': multipartRequestBody
        });
        request.execute(function(resp) { alert(resp); });
    }
    xmlhttp.open("GET", foldername + filename, true);
    xmlhttp.responseType = "arraybuffer";
    xmlhttp.send();
}
Gabor
  • 61
  • 2
  • I would refer you to this [link](http://stackoverflow.com/questions/10317638/inserting-file-to-google-drive-through-api) and here a documentation about the [request format](https://developers.google.com/drive/v2/reference/files/insert#examples). I hope it can help you. :) – Mr.Rebot Mar 23 '16 at 03:45
  • Thanks, but the recommended sites are among those that the codes in my question are based on. – Gabor Mar 24 '16 at 07:07
  • Your code inherently converts an object into its string representation: `var multipartRequestBody = ... + '\r\n\r\n' +contentData + '\r\n--' + ...;` ... having said that, I myself ended up base64-encoding my payload (along with a `Content-Transfer-Encoding` header) because `gapi.client` is very poor at handling binary content in its payload - it just `JSON.stringify()`s any objects thrown at it, and passes-through the rest, with no respect for `arraybuffer`s, `Blob`s and the like. (I was posting a direct binary, not a multipart - but the problem remains, regardless.) – Janaka Bandara Jul 29 '19 at 15:39

0 Answers0