小謝第7問:js前端如何實現大文件分片上傳、上傳進度、終止上傳以及刪除服務器文件?


文件上傳一般有兩種方式:文件流上傳和base64方式上傳,毫無疑問,當進行大文件上傳時候,轉為base64是不現實的,因此用formData方式結合文件流,直接上傳到服務器

本文主要結合vue的來講解,主要知識點有“promise函數、formData對象使用、ajax異步上傳、文件切割

//1、這里先在vue的Data中定義幾個上傳所需要的變量
            taskId: '' //區分分包文件名
            bytesPerPiece: 1 * 1024 * 1024, // 每個文件切片大小定為1MB .
            totalPieces: 0,//文件切片個數
            blob: '',//原始文件
            start: 0,//第一個分片
            end: 0,//最后一個分片
            index: 1,//分片次序
            filesize: 0,//文件大小
            chunk: 0,//文件分片
            formData: new FormData(),//后端header所需對象
// 2、分片上傳方法--這里的ajax如果項目封裝了axios可以直接改為axios,以避免使用jquery,使項目體積增大
        fileSlice(){ 
            return new Promise((resolve, reject) => {
                var _this = this;
                if (this.start < this.filesize) {     //判斷剩余文件大小,大於起始值執行切割操作
                    this.end = this.start + this.bytesPerPiece;        //規定分片文件節點
                    if (this.end > this.filesize) {  //判斷是否是最后一個切片
                        this.end = this.filesize;
                    } 
                    this.chunk = this.blob.slice(this.start, this.end); //切割文件 
                    this.sliceIndex = this.index;
                    this.percentage = parseInt((this.sliceIndex / this.totalPieces) * 100);   // 進度提示,如果不需要進度可省略
                    if(this.percentage == 0){  // 這里是因為當文件過大時候,避免進度顯示過慢,影響用戶體驗
                        this.percentage = 1;
                    }
                    console.log('sliceIndex', this.sliceIndex, 'this.percentage', this.percentage);
                    this.formData = new FormData();
                    this.formData.append('file', this.chunk); 
                    $.ajax({
                        type: 'post',
                        url:            //后端接口
                        headers: {             //后端所需參數
                            'jwt-token': Auth.getJwtToken(),
                            taskId: _this.taskId,
                            chunk: _this.sliceIndex,
                            size: _this.chunk.size,
                            chunkTotal: _this.totalPieces,
                            orginFileName: 'uploadFile'
                        },
                  //傳入組裝的參數
                        data: this.formData,
                        dataType: 'json',
                        async: true,
                        cache: false, //上傳文件不需要緩存
                        contentType: false, //需設置為false。因為是FormData對象,且已經聲明了屬性enctype="multipart/form-data"
                        processData: false, //需設置為false。因為data值是FormData對象,不需要對數據做處理
                        success: function(res) {   
                            if (_this.sliceIndex == _this.totalPieces) {    //判斷是否為最后一個文件,如果是,賦值后端輸出路徑 像服務端上傳文件
                                _this.upPath = res.data.path; 
                                _this.buttonLoading = false;
                            }
                            if(res.code == 0){ 
                                resolve('0'); 
                            }else{
                                _this.clearUploadFile();
                                reject(res.message);      
                            }
                        },
                        error: function(res) {          //異常判斷
                            reject('上傳文件失敗,請重新上傳!', this.fileList = []);
                            _this.$message({
                                message: res.message,
                                type: 'error'
                            }); 
                            return 'break';
                        }
                    }); 
                }
                _this.start = this.end;
                _this.index++;
            });
        },
        async fileUpload(file) { //此處主要給文件加32位隨機數
            console.log(file.file);
            this.blob = file.file; 
            this.filesize = this.blob.size;
            this.totalPieces = Math.ceil(this.filesize / this.bytesPerPiece); 
            function randomWord(randomFlag, min, max) {
        // eslint-disable-next-line one-var
                let str = '',
                    range = min,
                    arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
                        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
                        't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
                        'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
                        'V', 'W', 'X', 'Y', 'Z'
                    ];
        // 隨機產生
                if (randomFlag) {
                    range = Math.round(Math.random() * (max - min)) + min;
                }
                for (var i = 0; i < range; i++) {
                    let pos = Math.round(Math.random() * (arr.length - 1));
                    str += arr[pos];
                }
                return str;
            } this.taskId = randomWord(false, 32);   for(let i = 0; i < this.totalPieces; i++){  
                let ttt = await this.fileSlice().catch((res) => {   
                    this.$message({
                        message: res,
                        type: 'error'
                    });
                });
                if(ttt != 0){
                    break;
                } 
            }
        },
 
         

 

 
 
         
//3、中止文件上傳
        clearUploadFile(){
            // buttonLoading
            this.buttonLoading = false;
            this.totalPieces = 0;
            this.blob = '';
            this.start = 0;
            this.end = 0;
            this.index = 1;
            this.filesize = 0;
            this.chunk = 0; this.percentage = 0;
            // 清空文件表
            this.fileList = [];  
            const mainImg = this.$refs.upload;
            if (mainImg && mainImg.length) {
                mainImg.forEach(item => {
            // item.uploadFiles.length = 0;
                    item.clearFiles();
                });
            } 
        },

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM