6

I am experimenting with web Workers to improve file upload performance. I am working on an example from this post about large file uploads. I have a (somewhat) more complete code sample 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 server code to share, but the client side code is enough to see whether the browser is pushing the slices. According to MDN, File and FileList are both clonable objects, so is this a bug in Firefox?

The original link came via this post on StackOverflow.

In Firefox, I hit an error:

(DataCloneError: The object could not be cloned.)

on 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;
    }
 // FileList object.

 worker.postMessage({
 'files' : files
 });
 //Sending File list to worker
 // files is a FileList of File objects. List some properties.
 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';
 // Explicitly show this is a copy.
}

function setcode(){
 // Setup the dnd listeners.
 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;
  // 1MB chunk sizes.
  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()
 }

}
Community
  • 1
  • 1
Robert Munn
  • 778
  • 7
  • 12
  • The specification this article refers to also says *"If `input` has been disabled through the `close()` method, throw a `DataCloneError` exception and abort the overall structured clone algorithm."* Maybe Files are closed? *edit:* Not sure if browser implement this method already :-/ – Felix Kling Aug 14 '14 at 03:52
  • @Felix, According to the spec that only applies if input is a Blob object. In this case, input is a FileList object. I have some semi-working server-side code now, so I know the process works on Chrome and Safari. – Robert Munn Aug 14 '14 at 06:42
  • It seems duplicates http://stackoverflow.com/questions/26055730/transfer-file-to-webworker-datacloneerror-the-object-could-not-be-cloned – Singagirl Mar 09 '15 at 05:55

0 Answers0