I am experimenting with web workers to improve file upload performance. I am working on an example from this post about downloading large files . I have a (somewhat) more complete code example that works in Chrome (36.0.1985.143) and Safari (7.0.3 (9537.75.14)), but not in Firefox (31.0). I don’t have a server code to share, but the client-side code is enough to see if the browser clicks fragments. According to MDN , File and FileList are cloned objects, so is this a bug in Firefox?
The original link appeared through this post on StackOverflow.
In Firefox, I hit an error:
(DataCloneError: object cannot be cloned.)
in this line:
worker.postMessage({
'files' : files
});
Code follows:
index.html
<html>
<head>
<script>
var worker = new Worker('fileupload.js');
worker.onmessage = function(e) {
alert(e.data);
}
worker.onerror = werror;
function werror(e) {
console.log('ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message);
}
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files;
if(evt.dataTransfer === undefined ){
files = document.getElementById('files').files;
}else{
files = evt.dataTransfer.files||evt.target.files;
}
worker.postMessage({
'files' : files
});
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes, last modified: ', f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a', '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
}
function setcode(){
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
document.getElementById('files').addEventListener('change', handleFileSelect, false);
}
</script>
</head>
<body >
<input type="file" id="files" name="files" multiple />
<div id="drop_zone" style="width:500px;height:50%;">
Drop files here
</div>
<div>
<input type>
</div>
<output id="list"></output>
<script>
setcode();
</script>
</body>
</html>
fileupload.js
var file = [], p = true;
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', false);
xhr.onload = function(e) {
};
xhr.send(blobOrFile);
}
function process() {
for (var j = 0; j <file.length; j++) {
var blob = file[j];
const BYTES_PER_CHUNK = 1024 * 1024;
const SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
while (start < SIZE) {
if ('mozSlice' in blob) {
var chunk = blob.mozSlice(start, end);
} else if ('webkitSlice' in blob) {
var chunk = blob.webkitSlice(start, end);
}else{
var chunk = blob.slice(start, end);
}
upload(chunk);
start = end;
end = start + BYTES_PER_CHUNK;
}
p = ( j = file.length - 1) ? true : false;
self.postMessage(blob.name + " Uploaded Succesfully");
}
}
self.onmessage = function(e) {
for (var j = 0; j < e.data.files.length; j++)
file.push(e.data.files[j]);
if (p) {
process()
}
}