• 小谢第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();
                    });
                } 
            },
     
  • 相关阅读:
    KALI LINUX 核心概念讲解,持续更新
    KALI LINUX 工具大全之密码破解 --- BruteSpray ( 暴力喷雾 )
    android studio的 gradle 依赖同步错误解决方法
    安卓逆向的初步研究--从某恋app入手
    nc浏览器的十宗罪
    手机重要文件目录(换新机可能要用到)
    国产手机的谷X服务
    安卓手机设置的那些琐事
    办公中遇见的那些问题
    装系统遇到的那些问题
  • 原文地址:https://www.cnblogs.com/xieoxie3000question/p/13023616.html
Copyright © 2020-2023  润新知