How to download, zip and save multiple files with Javascript and get progress?

前端 未结 3 840
甜味超标
甜味超标 2020-12-29 17:30

I\'m creating a Chrome extension that needs to download multiple files (images and/or videos) from a website. These files may have a huge size, so I want to show the downloa

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-29 17:48

    Based on the @guari code, I tested it locally and applied it to the react application, attaching the code for others' reference.

    import JSZip from "jszip";
    import saveAs from "jszip/vendor/FileSaver.js";
    
    // .......
    
    // download button click event
    btnDownloadAudio = record =>{
        let fileURLs = ['https://www.test.com/52f6c50.AMR', 'https://www.test.com/061940.AMR'];
        let count = 0;
        let zip = new JSZip();
        const query = { record, fileURLs, count, zip };
        this.downloadFile(query, this.onDownloadComplete);
    }
    downloadFile = (query, onSuccess) => {
        const { fileURLs, count, } = query;
        var xhr = new XMLHttpRequest();
        xhr.onprogress = this.calculateAndUpdateProgress;
        xhr.open('GET', fileURLs[count], true);
        xhr.responseType = "blob";
        xhr.onreadystatechange = function (e) {
            if (xhr.readyState == 4) {
                if (onSuccess) onSuccess(query, xhr.response);
            }
        }
        xhr.send();
    }
    onDownloadComplete = (query, blobData) => {
        let { record, fileURLs, count, zip } = query;
        if (count < fileURLs.length) {
          const _this = this;
          const { audio_list, customer_user_id, } = record;
          this.blobToBase64(blobData, function(binaryData){
            // add downloaded file to zip:
            var sourceFileName = fileURLs[count].substring(fileURLs[count].lastIndexOf('/')+1);
            // convert the source file name to the file name to display
            var displayFileName = audio_list[count].seq + sourceFileName.substring(sourceFileName.lastIndexOf('.'));
            zip.file(displayFileName, binaryData, {base64: true});
            if (count < fileURLs.length -1){
                count++;
                _this.downloadFile({ ...query, count }, _this.onDownloadComplete);
            }
            else {
                // all files have been downloaded, create the zip
                zip.generateAsync({type:"blob"}).then(function(content) {
                    // see FileSaver.js
                    saveAs(content, `${customer_user_id}.zip`);
                });
            }
          });
        }
    }
    blobToBase64 = (blob, callback) => {
        var reader = new FileReader();
        reader.onload = function() {
            var dataUrl = reader.result;
            var base64 = dataUrl.split(',')[1];
            callback(base64);
        };
        reader.readAsDataURL(blob);
    }
    calculateAndUpdateProgress = (evt) => {
        if (evt.lengthComputable) {
            // console.log(evt);
        }
    }

提交回复
热议问题