2012-09-27 16 views
6

Estoy tratando de hacer un cargador de html para archivos muy grandes usando HTML5 y Web Workers. Atm carga lentamente pero consume mucha memoria. Creo que está transfiriendo todo el archivo a la memoria cuando lo agrega al formulario. Aquí está el código: jswebworker.js:Trabajador web de Javascript Subir archivo

/*importScripts('webworkerFormData.js');*/ 

(function() { 
// Export variable to the global scope 
(this == undefined ? self : this)['FormData'] = FormData; 

var ___send$rw = XMLHttpRequest.prototype.send; 
XMLHttpRequest.prototype['send'] = function(data) { 
    if (data instanceof FormData) { 
     if (!data.__endedMultipart) data.__append('--' + data.boundary + '--\r\n'); 
     data.__endedMultipart = true; 
     this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + data.boundary); 
     data = new Uint8Array(data.data).buffer; 
    } 
    // Invoke original XHR.send 
    return ___send$rw.call(this, data); 
}; 

function FormData() { 
    // Force a Constructor 
    if (!(this instanceof FormData)) return new FormData(); 
    // Generate a random boundary - This must be unique with respect to the form's contents. 
    this.boundary = '------RWWorkerFormDataBoundary' + Math.random().toString(36); 
    var internal_data = this.data = []; 
    /** 
    * Internal method. 
    * @param inp String | ArrayBuffer | Uint8Array Input 
    */ 
    this.__append = function(inp) { 
     var i=0, len; 
     if (typeof inp === 'string') { 
      for (len=inp.length; i<len; i++) 
       internal_data.push(inp.charCodeAt(i) & 0xff); 
     } else if (inp && inp.byteLength) {/*If ArrayBuffer or typed array */ 
      if (!('byteOffset' in inp)) /* If ArrayBuffer, wrap in view */ 
       inp = new Uint8Array(inp); 
      for (len=inp.byteLength; i<len; i++) 
       internal_data.push(inp[i] & 0xff); 
     } 
    }; 
} 
/** 
* @param name  String         Key name 
* @param value String|Blob|File|Uint8Array|ArrayBuffer Value 
* @param filename String         Optional File name (when value is not a string). 
**/ 
FormData.prototype['append'] = function(name, value, filename) { 
    if (this.__endedMultipart) { 
     // Truncate the closing boundary 
     this.data.length -= this.boundary.length + 6; 
     this.__endedMultipart = false; 
    } 
    var valueType = Object.prototype.toString.call(value), 
     part = '--' + this.boundary + '\r\n' + 
      'Content-Disposition: form-data; name="' + name + '"'; 

    if (/^\[object (?:Blob|File)(?:Constructor)?\]$/.test(valueType)) { 

     return this.append(name, 
         new Uint8Array(new FileReaderSync().readAsArrayBuffer(value)), 
         filename || value.name); 
    } else if (/^\[object (?:Uint8Array|ArrayBuffer)(?:Constructor)?\]$/.test(valueType)) { 
     part += '; filename="'+ (filename || 'blob').replace(/"/g,'%22') +'"\r\n'; 
     part += 'Content-Type: application/octet-stream\r\n\r\n'; 
     this.__append(part); 
     this.__append(value); 
     part = '\r\n'; 
    } else { 
     part += '\r\n\r\n' + value + '\r\n'; 
    } 
    this.__append(part); 
}; 
})(); 

movies = []; 
var timeStarted = 0; 
uploadingVar = false; 
const BYTES_PER_CHUNK = 64 * 1024 * 1024; 

function toTitleCase(str) 
{ 
return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1);}); 
} 

function newUpload(blobOrFile, moviename, filename, i, fileType, sizeFile) { 
var xhr = new XMLHttpRequest(); 
path = '/moviehtml/newmupload.php?  moviename='+escape(moviename)+'&filename='+escape(filename)+'&num='+escape(i); 
xhr.open('POST', path, false); 
self.postMessage(blobOrFile.size); 
var fd = new FormData(); 
//xhr.setRequestHeader('Content-Type', fileType) 
//blobOrFile2 = FileReaderSync.readAsArrayBuffer(blobOrFile); 
fd.append("files1", blobOrFile); 
//fd.append("moviename", moviename); 
//fd.append("filename", filename); 
//fd.append("num",i); 

seconds = new Date()/1000; 
xhr.send(fd); 
self.postMessage(xhr.responseText) 
self.postMessage({'type':'partial','done':i*BYTES_PER_CHUNK, 'started':timeStarted, 'total':sizeFile}); 
var finish = Date()/1000; 
if (finish >= (seconds+100)){ 
    return false; 
} 
return true; 

} 
function newFileUpload(file, movieName, fileType, filename, exten){ 
if (movieName == movieName.match(/[a-zA-Z0-9\. \:]+/)){ 
    timeStarted = new Date().getTime(); 

var blob = file;// this.files[0]; 
//var filename = blob.name; 
var moviename = toTitleCase(movieName); 
// 1MB chunk sizes. 
const SIZE = blob.size; 
//alert(SIZE + ' '+document.getElementById('fileToUpload').files[0].size) 
var start = 0; 
var end = BYTES_PER_CHUNK; 
//alert(SIZE/BYTES_PER_CHUNK) 
var i = 1; 
while(start < SIZE) { 
    wow = newUpload(blob.slice(start, end), moviename, filename, i, fileType, SIZE); 

    start = end; 
    end = start + BYTES_PER_CHUNK; 
    i++; 
} 
var xhr = new XMLHttpRequest(); 
var fd2 = new FormData(); 
typeFile = filename.split('.').pop() 
fd2.append("type", blob.type); 
fd2.append("exten", typeFile); 
fd2.append("moviename", moviename); 
xhr.open('POST', '/moviehtml/finishedupload.php', false); 
xhr.send(fd2); 
} 
} 
function process(){ 
uploadingVar = true; 
while(movies.length > 0) { 

    upMovie = movies.pop(); 
    var file = upMovie[0]; 
    var movieName = upMovie[1]; 
    var fileType = upMovie[2]; 
    var filename = upMovie[3]; 
    var exten = upMovie[4]; 
    self.postMessage({'type':'start','size':file.size, 'name':movieName}); 

    newFileUpload(file, movieName, fileType, filename, exten); 
    self.postMessage({'type':'finish','name':movieName}) 
    self.postMessage(movieName + " Uploaded Succesfully"); 
} 
uploadingVar = false; 
} 

self.addEventListener('message', function(e) { 
movies.push(e.data); 
if (!uploadingVar){ 
process(); 

} 
}, false); 

Mi función que llama:

var worker = new Worker('jswebworker.js'); 
function testUpload(){ 
//newFileUpload(); 
var file = document.getElementById('fileToUpload').files[0]; 
worker.postMessage([file,toTitleCase(document.getElementById('movieName').value),  file.type, file.name, file.name.split('.').pop()]); 

} 

Esta es la página web para un servidor de medios de mi piso. Espero que haya una forma de crear un blob sin cargar todo el original en la memoria. Gracias por cualquier ayuda, Nick

+0

¿Dónde puede encontrar una solución? – Hadesara

+0

¿Por qué no proporciona un código más simple? Creo que más personas realmente lo leerían si lo haces. – stevemao

Respuesta

1

creo que this biblioteca (en este caso es la página de GitHub para resumable.js también) pueden estar ya haciendo lo que está tratando demasiado lograr. Como no sé cuán grandes son los archivos que desea cargar, no puedo ofrecer ninguna información sobre los puntos de referencia. Espero que esto te ayude.

Cuestiones relacionadas