I'm creating a Google Chrome extension which use Google Drive API.
I have to upload a file with HTML5.
For text files, there is no problem. But when I want to upload a binary file, there are always errors.
So when I upload a file using the FileReader in HTML5 as BinaryString, my image is corrupted, I can't read it.
And when I use Base64 encoding (with the header in the body part "Content-Transfer-Encoding: base64"), I have a 400 Bad Request -> Malformed multipart body.
Can you help me please ?
Thanks :)
PS: I don't want to use Google Drive SDK, I prefer 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 Upload, just modify this line :
reader.readAsDataURL(bb.getBlob('image/png'));
by that
reader.readAsBinaryString(bb.getBlob('image/png'));
and delete this line :
parts.push('Content-Transfer-Encoding: base64');
I tried to create a file by sending the metadata first and upload the content after like in this post and I always get a 404 error for uploading the content, but this is another story...
An empty line which consists of only \r\n and no other whitespace need to be added at the end of your request. Try to add another parts.push('');
after parts.push('--' + bound + '--');
Edit:
First, I want to say that you should not upload file as raw Binary String because your binary data contains control characters which may screw up your request and results in corrupted file. Data should be encoded in Base64. You can read more here
If you check reader.result
in debug, 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
method DID encode your data to base64 but because it is used to produce Data URI , a string with format as data:[<MIME-type>][;charset=<encoding>][;base64],
is added at the begin of your encoded data. This is the culprit cause 400 Bad Request
error (Malformed multipart body).The solution is to eliminate this string before adding it to the request body:
parts.push(reader.result.replace(/^data:image\/(png|jpg);base64,/, ""));
I have tested and it works fine.