2016-01-14 63 views
16

Mam naprawdę dziwny problem tylko w Google Chrome i Chromium.Przesyłanie obiektów blobs jako wieloczęściowego przesyłania powoduje: net :: ERR_FILE_NOT_FOUND w Chrome po 500mb

Tło jest:

przesyłać pliki do serwera za pomocą metody przesyłania wieloczęściowe, co oznacza, że ​​złamię pliki na kawałki 10mb i wysłać każdy klocek do serwera. Działa to bezbłędnie we wszystkich przeglądarkach z plikami o dowolnym rozmiarze, problem zaczął się, gdy potrzebowałem zaszyfrować każdą porcję.

Dla szyfrowania używam CryptoJS, a przed przesłaniem kawałek, ja szyfruje je i uzyskać wynikające Blob przesłać, to działa prawidłowo na Chrome kiedy muszę przesłać mniej niż 50 kawałków (50 plamy, około 500mb w sumie) , potem dostaję POST http://(...) net::ERR_FILE_NOT_FOUND.

To dziwne, działa to we wszystkich innych przeglądarkach, w tym w Operze, która obecnie jest w zasadzie Chrome, z wyjątkiem Chrome i Chromium. Testowałem go na IE, Firefox, Edge, Safari, Opera, Chrome i Chromium.

Poniżej możesz zobaczyć, jak działa mój kod, abyście mogli mieć pomysł, to nie jest prawdziwy kod, którego używam w aplikacji, ale raczej kod testowy, który napisałem, który daje taki sam wynik.

Zamiast się kawałek (File.slice) pliku mam zamiar przesłać jako klocek i szyfrowanie to, aby uzyskać blob, mam zamiar generować fałszywe blob z wielkością mojego kawałka. Wstawiłem setTimeout, aby zasymulować czas potrzebny na zaszyfrowanie obiektu typu blob. Jak powiedziałem wcześniej, mam taki sam wynik jak moje prawdziwe kodu w ten sposób:

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); 
} 

więc powyższy kod jest gdzie moja kropelka jest generowany, poniżej jest częścią Dodano:

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); 
    });             
} 

Oczywiście nie ma tutaj innych zmiennych pomocniczych i kodu, ale to wystarczy, by dać wyobrażenie o tym, z czym mamy do czynienia.

W tym przykładzie używam modułu AngularJS '$http, ale próbowałem również z czystym XMLHttpRequest i otrzymałem taki sam wynik.

Tak jak powiedziałem, dostaję tylko POST http://(...) net::ERR_FILE_NOT_FOUND z plikami większymi niż 499 MB (50+ porcji) i tylko w Chrome.

jestem delegowania to tutaj jak szukałem rozwiązania, ale nie mogłem znaleźć nic związanego z tym problemu, najbliższa rzecz znalazłem w internecie był ten problem na forum projektu Chromium:

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

w tym momencie ja naprawdę nie wiem co robić już więc chciałbym wiedzieć, czy ktoś miał podobny problem w przeszłości i może jakoś to naprawić.

Dziękuję za odpowiedzi z góry.

+0

Ja również uderzanie ten sam problem z tuż przy użyciu XMLHTTPRequest, nawet szyfrowanie kawałki. Czy miałeś szczęście dowiedzieć się, co się dzieje? – harun

+0

Niestety musiałem ustawić limit w mojej aplikacji na 400 MB. Wygląda na to, że jest to błąd lub ograniczenie w Chrome, które sprawia, że ​​bloby po 500mb są czystymi śmieciami. Wciąż mam nadzieję na rozwiązanie. –

+0

Jestem w tym samym scenariuszu co @ Eric.M. Naprawdę potrzebuję rozwiązania i wszystko, co znalazłem, to błąd przeglądarki Chrome. – gpalomar

Odpowiedz

-1

Wygląda na to, że to wtyczka Firebug. Spróbuj go wyłączyć. Mi to pasuje.

Przeglądarka Firefox. Wystąpił problem podczas ładowania pliku przez porcje. Wyłączyłem wtyczki i wyciek pamięci nie pojawia się. Może to ci pomoże

Dla Chrome wszystko działa dobrze.

+1

Problem jest w Chrome. –

1

Chrome może przydzielić tylko 500 MB na dowolny blob, więc jeśli spróbujesz przydzielić 500mb + 1 bajt, będzie to oczywiście ignorować ten bajt, aby rozwiązać ten problem, będziesz musiał odczytać plik w kawałkach 499mb, a następnie będziesz mieć scalić plik na serwerze.

Możesz też wypróbować coś takiego jak ZipJS, a następnie przesłać suwak, który zadziałał.

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