zoukankan      html  css  js  c++  java
  • 小谢第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();
                    });
                } 
            },
     
  • 相关阅读:
    LeetCode 515. 在每个树行中找最大值(Find Largest Value in Each Tree Row)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 1022. 从根到叶的二进制数之和(Sum of Root To Leaf Binary Numbers)
    LeetCode 897. 递增顺序查找树(Increasing Order Search Tree)
    LeetCode 617. 合并二叉树(Merge Two Binary Trees)
    LeetCode 206. 反转链表(Reverse Linked List) 16
    LeetCode 104. 二叉树的最大深度(Maximum Depth of Binary Tree)
    LeetCode 110. 平衡二叉树(Balanced Binary Tree) 15
    LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
  • 原文地址:https://www.cnblogs.com/xieoxie3000question/p/13023616.html
Copyright © 2011-2022 走看看