File compression before upload on the client-side

前端 未结 6 1073
栀梦
栀梦 2020-12-24 15:12

Basically I\'ll be working with large XML files (approx. 20 - 50 MB). These files needs to be uploaded on a server.

I know it isn\'t possible to touch the files with

6条回答
  •  [愿得一人]
    2020-12-24 16:03

    You can make use of JSZip. For input, it supports String/ArrayBuffer/Uint8Array/Buffer, but not blobs, which is what you get from an with javascript:

    A File object is specific kind of a Blob, and can be used in any context that a Blob can

    (link)

    So you'll have to convert the blob/file to e.g. an ArrayBuffer first, e.g. using FileReader.readAsArrayBuffer(). Note that this function works asynchronously, demanding callback usage. There is also a FileReaderSync available, yet "This interface is only available in workers as it enables synchronous I/O that could potentially block", so I don't see any good in using it.

    (EDIT. I'm not sure but I believe you can skip the blob->ArrayBuffer conversion now and simply zip the File object.)

    This whole approach is specially useful if php's directive max_file_uploads was set to a small number by your webspace host, for now the only thing you'll have to worry about is upload_max_filesize

    For reference, a code sample excerpt follows (using JQuery) for putting several files of one multiple file input in a zip before submitting:

    // onclick:
    var fileInput = $(':file');
    var files = [];
    $.each(fileInput[0].files, function(i, file) {
        files.push(file);
    });
    
    var zip = new JSZip();
    function addFileToZip(n) {
        if(n >= files.length) {
            zippingComplete(zip.generate({type:"blob", compression:"deflate"}));
            return;
        }
        var file = files[n];                    
        var arrayBuffer;
        var fileReader = new FileReader();
        fileReader.onload = function() {
            arrayBuffer = this.result;
            zip.file(file.name, arrayBuffer);
            addFileToZip(n + 1);
        };
        fileReader.readAsArrayBuffer(file);
    }
    addFileToZip(0);
    
    function zippingComplete(zip) {
        formData = new FormData();
        formData.append('fileZip', zip);
        formData.append("param1", "blah");
        $.ajax({
            data: formData,
            //... etc
    

    Server-side-wise, you'll access $_FILES["fileZip"].

提交回复
热议问题