WebUploader - 分片上传

在开发过程中遇到需要上传大文件的需求,但是大文件整个上传会导致服务器内存爆炸。

分片上传的思路

利用blob.slice()方法,根据指定的分片大小对文件进行切割,然后对切割得到的分片分开上传,上传可以指定并发数。服务器接受到所有分片之后,在把所有分片按照正确的顺序合并成完整的文件。

实现

由于实现过程中,后端开发懒得去判断分片是否全部上传完毕,需要前端在分片全部上传完之后在发送一个请求通知后台合并分片。并且webupload对image 类型的文件不分片。最后封装webuploader实现如下:

function upload(file, options) {
    
    
    // default options
    options = $.extend({
    
    
        folder: '',
        success: $.noop,
        error: $.noop,
        progress: $.noop
    }, options);

    var errorHandler = options.error;
    var successHandler = options.success;
    var progressHanlder = options.progress;
    var fileMd5 = uuidv4();
    var runtimeForRuid = new WebUploader.Runtime.Runtime();
    var wuFile = new WebUploader.File(new WebUploader.Lib.File(WebUploader.guid('rt_'), file));
    var chunkSize = 1 * 1024 * 1024;
    var chunked = file.size > chunkSize;
    // 
    var events = $.extend({
    
    
        uploadBeforeSend: function(_, data) {
    
    
            if (chunked) {
    
    
                data.uuid = fileMd5;
            }
        },
        uploadProgress: progressHanlder
    }, file.type.indexOf('image') >= 0 || !chunked ? {
    
    
        uploadSuccess: function(_, data) {
    
    
            successHandler(data);
        },
        uploadError: function() {
    
    
            errorHandler('上传失败');
        }
    } : {
    
    
        uploadFinished: function() {
    
    
            var file = uploader.getFiles()[0];
            if (!file || file.type.indexOf('image') >= 0) {
    
    
                return;
            }

            $.post('/public/stream-file/', {
    
    
                csrf_token: bms.csrf_token,
                chunk: -1,
                uuid: fileMd5,
                upload_folder: options.folder,
                name: file.name
            }, null, 'json').done(successHandler).fail(function() {
    
    
                errorHandler('上传失败');
            });
        }
    });
    
    var uploader = WebUploader.create({
    
    
        fileNumLimit: 1,
        chunked: chunked,
        chunkSize: chunkSize,
        prepareNextFile: true,
        server: '/public/stream-file/',
        fileVal: 'attachement',
        formData: {
    
    
            csrf_token: bms.token,
            upload_folder: options.folder
        }
    });

    $.each(events, function(name, handler) {
    
    
        uploader.on(name, handler);
    });

    // 开始上传
    uploader.addFiles(wuFile);
    uploader.upload();
    return uploader;
}

猜你喜欢

转载自blog.csdn.net/WuLex/article/details/109115489