Upload file to Google Drive API using HTML5

I am creating a Google Chrome extension using the Google Drive API. I need to download a file with HTML5.

There are no problems for text files. But when I want to download a binary file, there are always errors.

Therefore, when I upload a file using FileReader in HTML5 as a BinaryString, my image is damaged, I can not read it.

And when I use Base64 encoding (with a heading in the main part of "Content-Transfer-Encoding: base64"), I have 400 Bad Request โ†’ Malformed multipart body.

Can you help me? Thanks:)

PS: I donโ€™t want to use the Google Drive SDK, I prefer to write all the code.

var bb, reader; var meta = { "title": "mozilla.png", "mimeType": "image/png", "description": "Mozilla Official logo" }; var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://developer.mozilla.org/media/img/mdn-logo-sm.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function(e){ if(this.status == 200){ bb = new WebKitBlobBuilder(); bb.append(this.response); console.log('Download OK'); reader = new FileReader(); reader.readAsDataURL(bb.getBlob('image/png')); reader.onloadend = function(e){ console.log('Reader OK'); var bound = 287032396531387; var parts = []; parts.push('--' + bound); parts.push('Content-Type: application/json'); parts.push(''); parts.push(JSON.stringify(meta)); parts.push('--' + bound); parts.push('Content-Type: image/png'); parts.push('Content-Transfer-Encoding: base64'); parts.push(''); parts.push(reader.result); parts.push('--' + bound + '--'); var xhr = new XMLHttpRequest(); xhr.open("POST", "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart", true); xhr.setRequestHeader("Authorization", "Bearer token123456"); xhr.setRequestHeader("Content-Type", "multipart/mixed; boundary=" + bound); xhr.onload = function(e){ console.log("DRIVE OK", this, e); }; xhr.send(parts.join("\r\n")); } } }; xhr.send(); 

For binary loading, just change this line:

 reader.readAsDataURL(bb.getBlob('image/png')); 

the fact that

 reader.readAsBinaryString(bb.getBlob('image/png')); 

and delete this line:

 parts.push('Content-Transfer-Encoding: base64'); 

I tried to create the file by first sending the metadata and uploading the content, as in this post, and I always get a 404 error to load the content, but this is another story ...

+3
source share
1 answer

At the end of your query, you need to add an empty string consisting only of \ r \ n and no other spaces. Try adding more parts.push(''); after parts.push('--' + bound + '--');

Edit:

Firstly, I want to say that you should not download the file as a raw binary string, because your binary data contains control characters that can ruin your request and lead to file corruption. Data must be encoded in Base64. You can read here

If you check reader.result in debugging, it will contain:

 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABHCAMAAABoMgR/AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJlQTFRFAAAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAAwAAEgICExAQIAQFIyAgLwYHMjAwPggJQkBATAoLUlBQWwwOYmBgaQ4QcXBweBASgYCAhxIUkIKCkY+PlRQXoZ+fpBYZrYaGsK+vsxgbwL+/wRod0Bwg0M/P3h4i4N/f7SAk7+/v9pCS////7yG8VgAAAA90Uk5TABAgMEBQYHCAn6+/z9/vBoviEQAABBtJREFUWMOtmA13mzoMhumWdd3uWpuPACUEWIkXA3HI+P8/7kq2AYOBNj1Tz2nA9oOl10KAHUfZw+7p4/b41ZnY7j9yn708PQzww09yv7186+lf5FP2qHBJJ1y0H7am9JCR8z/BAa3bOy1B/zH+lzW6KJt3+CfHeYSfYqGboX9eylRMC5FB/7Pj/IBRdicPoTkOMMIgZWlAEmtIBn1fHFjx0JIGPQt40wiWSZGoZ/Mc2ncLuMgoABAQpXCWEi9hraAWv4KXFP1G1dIYBVSy1ha/iHOM12PzmdLU4hfwBhUj6VRKnqA/GfBxvYWLVCbjMDVLwrBoUOM9/JXAw0rWazgqhp63LMTIa4+mjBdeCiMl2IoyNq4wxWWaoGUwGzjASKxiKALwq6gHj+AK5RyXaaIMZoaxgga9AmlipWu5LJ1ISKwZNYVsnEmeeR66Z+O45KzPaBF7ujkkibkWRSiC0MbVkusxhLShbOesxcCCjI+J1WYWLhItXI9DAy5ASNtel3C4hIUXtBeOyduXkpKTgPGYZI3qqU6R319ihgtIELCABBi1ktcTMvvTNtZ4lXent1fpRRIuSVfj7Jzrw6ARnDcYlEyJox9dSHeqLsdXlyzimVF4CqyfWZYCmkBtxHzz96RyT+djl5PUxmXexaO+ZEhDfdfJ4nNwo4qQeo43Wt/WiERaahZodMJ1UaIJLrJ+LmZ6rxesqM1bn6oQTbzm0goyJii4ystErydN+qqNpSwUK9WGDmkndAbWKuS+akN+6Fpk4zKEelCud4SNzzVQNxMr1UY9ubTQsSEDRFCXiewN16pNraUPWsFl0tP5Hd6USbla61A6Jp9YWG2YIaIZyGalDWXe1BCennCQkX4Ah0rrieEBaJQIU4hVnI2612b6yhR69xnX0PGOyUbfOWVts+D9DBeBMWMw+s7wmsHgl41TXSuGwHG2YP4w98KpBT3e2/iOUszfOOrll6sJXppKN9aryBru59J+/x1sciLtTz63Q49H3Wes+nf4Fby59h2nPD+pJmln1QHnZ8VBWzXF8fig6SsZmrRFFz0b/kKdJSS3cVIp/NXCiXtR5/stPBpimuPkVZ/nGziRsUUGjhes9tjQD7ls4D7qRma41AIwPeS2jpO3rvMtvFO66CHHDdy95eQdnFTrODzB3sX94zLu9/3ruBziLuORctw9r+N5pKdYwm/y4m/VBn5113G5aPtuC+/OGzimTGXhp3Hdc5XSa/gF7xsD31fV+eiOWQfUzV3Hu/w2wQc7DPiQ+wrHL6mbEegivr+NeKfX/Si/pL7Jk03cR59GHBcol/+f1Veke7m/VmGl/A74d0yV6jP0s/yGl5X+cL7eUSXffFXl/8H3u/Pw4zO7Bztj7+Le7YdnY+9C7Zw8fnznZDfsnPwP488L21waSrUAAAAASUVORK5CYII= 

As you can see, the readAsDataURL DID method encodes your data in base64, but since it is used to create a data URI , a line with the format data:[<MIME-type>][;charset=<encoding>][;base64], added to beginning of your encoded data. This is the error cause error 400 Bad Request (Malformed multipart body). The solution is to eliminate this line before adding it to the request body:

 parts.push(reader.result.replace(/^data:image\/(png|jpg);base64,/, "")); 

I tested and works great.

+4
source

Source: https://habr.com/ru/post/1265274/


All Articles