I am trying to upload files through my web app using the following code.
View:
I use this workaround...
HTML:
JavaScript:
In JavaScript you can upload files using the 3 method:
var binBlob = []; // If you use AngularJS, better leave it out of the DOM
var fi = document.getElementById('uploadNewAttachment');
fi.onchange = function(e) {
r = new FileReader();
r.onloadend = function(ev) {
binBlob[binBlob.length] = ev.target.result;
};
//r.readAsDataURL(e.target.files[0]); // Very slow due to Base64 encoding
//r.readAsBinaryString(e.target.files[0]); // Slow and may result in incompatible chars with AJAX and PHP side
r.readAsArrayBuffer(e.target.files[0]); // Fast and Furious!
};
$(fi).trigger('click');
What we have, javascript side is an Uint8Array of byte with values from 0 to 255 (or a Int8Array -128 to 127).
When this Array is sent via AJAX, it is "maximized" using signs and commas. This increases the number of total bytes sent.
EX:
[123, 38, 98, 240, 136, ...] or worse: [-123, 38, -81, 127, -127, ...]
As you can see, the number of characters transmitted is oversized.
We can instead proceed as follows:
Before send data over AJAX, do this:
var hexBlob = [];
for(var idx=0; idx
What you have now, is a string of hex bytes in chars!
Ex:
3a05f4c9...
that use less chars of a signed or unsigned javascript array.
PHP: On the PHP side, you can decode this array, directly to binary data, simply using:
for($idx=0; $idx<=count($hexBlob); $idx++) {
// ...
$binData = pack('H*',$hexBlob[$idx]);
$bytesWritten = file_put_contents($path.'/'.$fileName[$idx], $binData);
//...
}
This solution worked very well for me.