2016-01-14 27 views
16

Sto avendo un problema davvero strano solo su Google Chrome e Chromium.Caricamento di BLOB come caricamento di più parti causa net :: ERR_FILE_NOT_FOUND su Chrome dopo 500mb

Lo sfondo è:

ho caricare i file sul mio server utilizzando il metodo di caricamento più parti, nel senso che mi rompo i file in blocchi di 10 MB e mando ogni blocco al server. Funziona perfettamente in tutti i browser con file di qualsiasi dimensione, il problema è iniziato quando avevo bisogno di crittografare ogni blocco.

Per la crittografia utilizzo CryptoJS e, prima di caricare il blocco, lo criptolo e il risultato dello Blob da caricare, funziona perfettamente su Chrome quando devo caricare meno di 50 blocchi (50 blob, circa 500mb in totale) , dopo di che ottengo uno POST http://(...) net::ERR_FILE_NOT_FOUND.

Stranamente, questo funziona su tutti gli altri browser, tra cui Opera che è fondamentalmente Chrome al giorno d'oggi, tranne Chrome e Chromium. L'ho provato su IE, Firefox, Edge, Safari, Opera, Chrome e Chromium.

Qui sotto puoi vedere come funziona il mio codice in modo che voi ragazzi potete avere un'idea, questo non è il codice reale che uso nell'app ma, piuttosto, è un codice di prova che ho scritto che produce lo stesso risultato.

Invece di ottenere una fetta (File.slice) del file che ho intenzione di caricare un pezzo e la crittografia per ottenere il blob, ho intenzione di generare un falso blob con le dimensioni del mio pezzo. Metto il setTimeout per simulare il tempo necessario per crittografare un blob. Come ho detto prima, ottengo lo stesso risultato come il mio vero e proprio codice in questo modo:

function uploadNext(prevResponse) { 
    if (currentPart == totalPartsFile) 
     return; 

    //var chunk = getNextChunk(); 
    var totalSize = file.size; 

    setTimeout(function() { 
     var blob = new Blob([new ArrayBuffer(constants.chunkSize)], { 
      type: 'application/octet-string', 
      name: file.name 
     }); 

     console.log(blob); 

     blob.encrypted = true; 
     blob.key = encryptionKey; 
     blob.mimeType = file.mimeType; 
     blob.name = file.name; 
     blob.originalFileSize = originalFileSize || file.size; 

     uploadFile(objectId, currentPart, blob, totalSize, prevResponse, function(resp) { 
      uploadNext(resp); 
     }); 
    }, 1000); 
} 

Quindi, il codice di cui sopra è in cui viene generato il mio blob, sotto c'è la parte upload:

function uploadFile (objectId, index, blob, totalSize, prevResponse, callback) { 

    var format = "encrypted"; 
    var params = "?format=" + format + (format === "encrypted" ? "&encoding=base64" : ""); 
    var endPoint = constants.contentServiceUrl + resourceService.availableResources.addContents.link.split(':objectId').join(objectId) + params; 

    var formData = new FormData(); 

    formData.append("totalFileSizeBytes", totalSize); 
    formData.append("partIndex", index); 
    formData.append("partByteOffset", previousOffset); 
    formData.append("chunkSize", blob.size); 
    formData.append("totalParts", totalPartsFile); 
    formData.append("filename", blob.name); 

    if (currentPart != 0) { 
     formData.append("uploadId", prevResponse.uploadId); 
     formData.append("bucket", prevResponse.bucket); 
    } 

    if (finalChunk) { 
     for (var key in etags1) { 
      formData.append("etags[" + key + "]", etags1[key]); 
     } 
    } 

    formData.append("data", blob); 

    previousOffset += blob.size; 

    var request = { 
     method: 'POST', 
     url: endPoint, 
     data: formData, 
     headers: { 
      'Content-Type': 'multipart/form-data' 
     } 
    } 

    $http(request) 
     .success(function(d) { 
      _.extend(etags1, d.etags); 
      console.log(d); 
      callback(d); 
     }) 
     .error(function(d) { 
     console.log(d); 
    });             
} 

Naturalmente ci sono altre variabili di supporto e codice che non ho inserito qui, ma questo è sufficiente per dare un'idea di cosa abbiamo a che fare.

In questo esempio sto usando il modulo $http di AngularJS, ma ho provato con puro XMLHttpRequest e ho ottenuto lo stesso risultato.

Come ho detto, ho solo il POST http://(...) net::ERR_FILE_NOT_FOUND con file più grandi di 499mb (50+ pezzi) e solo in Chrome.

sto postando questo qui come sto cercando una soluzione, ma non ho trovato nulla relative a questo problema, la cosa più vicina che ho trovato su internet è stato questo problema nel Forum progetto Chromium:

https://code.google.com/p/chromium/issues/detail?id=375297

a questo punto io davvero non so più cosa fare così mi piacerebbe sapere se qualcuno ha avuto un problema simile in passato e potrebbe risolvere il problema in qualche modo.

Grazie per le risposte in anticipo.

+0

Sono anche colpendo lo stesso problema con solo utilizzando XMLHTTPRequest, nemmeno la crittografia dei pezzi. Hai avuto fortuna a scoprire cosa sta succedendo? – harun

+0

Purtroppo ho dovuto impostare un limite nella mia app per 400mb. Sembra che si tratti di un bug o di una limitazione su Chrome, che fa sì che i BLOB dopo 500 MB siano spazzatura pura. Sto ancora sperando in una soluzione però. –

+0

Sono nello stesso scenario di @ Eric.M. Ho davvero bisogno di una soluzione e tutto quello che ho trovato è che si tratta di un bug di Chrome. – gpalomar

risposta

-1

Sembra, è il problema del plugin Firebug. Prova a disabilitarlo. Per me funziona.

Browser Firefox. Ho avuto un problema quando ho caricato file per blocchi. Ho disabilitato i plugin e la perdita di memoria non appare. Forse ti aiuterà

Per Chrome tutto funziona bene.

+1

il problema è su Chrome. –

1

Chrome può solo allocare 500mb per qualsiasi blob, quindi se si tenta di allocare 500mb + 1 byte, ignorerà chiaramente quel byte, per risolvere questo si dovrà leggere il file in blocchi di 499mb e quindi si avrà unire file sul server.

Oppure puoi provare qualcosa come ZipJS e quindi caricare lo zip, ha funzionato per me.

var zip = new JSZip(); 
    zip.file("file1", "content1"); 
    zip.file("file2", "content2"); 
Problemi correlati