Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
150
rated 0 times [  151] [ 1]  / answers: 1 / hits: 16965  / 12 Years ago, tue, august 21, 2012, 12:00:00

I need to upload a part of a file (only the first MB). I've created a PHP script which uploads the whole file. The data (formData Object) is passed by a ajax call.



My idea would be now to split the file with javascript (jquery). Is there any solution for my request?



Current code:



function start(a){
//var fSize = $('#fileUpload')[0].files[0].size / 1024;
var formData = new FormData();
formData.append( 'fileUpload', $('#fileUpload')[0].files[0] );
//AJAX
$.ajax({
url: 'script.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(msg){
alert(Win: + msg);
},
error: function(bla, msg){
alert(Fail: + msg);
}
});
}

More From » jquery

 Answers
6

Since you're using FormData, which is a fairly new technology, I'll show you something with new technologies as well.



First, read the file with a FileReader object:



var fr = new FileReader(), buf, file = $('#fileUpload')[0].files[0];
fr.onload = function(e) {
buf = new Uint8Array(e.target.result);
};
fr.readAsArrayBuffer(file);


Then you can create a Blob for each splitted part (1e6 bytes long each):



for (var i = 0, blobs = []; i < buf.length; i += 1e6)
blobs.push(new Blob([buf.subarray(i, i + 1e6)]));


Finally, you can add all your Blobs to your FormData object:



var formData = new FormData();
for (var i = 0; i < blobs.length; i++)
formData.append(slice + i, blobs[i], file.name + .part + i);


You should be ok. I haven't tested it, though.



I don't know anything about the performance either. You can use fr.readAsBinaryString too, thus making e.target.result a string. This way, you can create the Blobs using a simple substring/slice/substr/whatever, but I fear there could be some problems with Unicode characters and whatnot. Plus, maybe it's slower.



Putting everything in a more coherent snippet:



$('#fileUpload').change(function() {
// If no file is selected, there's nothing to do
if (!this.files.length) return;

var fr = new FileReader(), file = this.files[0];
fr.onload = function(e) {
splitAndSendFile(new Uint8Array(e.target.result), file);
};
fr.readAsArrayBuffer(file);
};

function splitAndSendFile(dataArray, file) {
var i = 0, formData, blob;
for (; i < dataArray.length; i += 1e6) {
blob = new Blob([dataArray.subarray(i, i + 1e6)]);
formData = new FormData();
formData.append(fileUpload, blob, file.name + .part + (i / 1e6));
$.ajax({
url: 'script.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(msg){
alert(Win: + msg);
},
error: function(bla, msg){
alert(Fail: + msg);
}
});
}
}


Note: FormData.append takes a third optional parameter, which should be the name of the file in case of File or Blob values. If not specified, Blobs may get unpredictable random file names.



Probably that parameter isn't standard, and it's not mentioned in the MDN artice, but I used it in the snippet above nonetheless. Anyway, if you know what you're doing, you can have several options to specify the file name. For example, with formData.append(filename, file.name) or sending a custom header in the request.


[#83508] Monday, August 20, 2012, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
kayle

Total Points: 267
Total Questions: 77
Total Answers: 99

Location: Central African Republic
Member since Mon, Aug 10, 2020
4 Years ago
;