webUploader实现大文件分片,断点续传

Posted hackxiyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webUploader实现大文件分片,断点续传相关的知识,希望对你有一定的参考价值。

问题:

  公司现在的业务需求是要上传一个大文件,上一次写了一篇博客,做了一个简单的文件上传,支持单文件,大型文件上传

  现在对之前的上传进行优化,支持断点续传,秒传功能

   上次博客:【http://www.cnblogs.com/hackxiyu/p/8194066.html

分析:

  这篇文章参考了其它博主的文章,参考地址:【https://github.com/Fourwenwen/Breakpoint-http】

  环境需要:

    1.本地测试的话需要配置好Redis,用来保存文件的MD5校验值,和秒传功能的实现

    2.jquery,bootstrap,webUploader的相关js,css文件

    3.我用的是springBoot来实现的,页面是首页嵌套的,所以没有html,body标签,大家根据自己情况来定

 

解决:

  1.页面html文件,业务js文件杂糅到一起,大家可以拆开清晰一些

<!--引入css文件-->
<link rel="stylesheet" type="text/css" href="static/html/bigFileUpload/assets/bootstrap-3.3.7-dist/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="static/html/bigFileUpload/assets/webuploader.css">

<div id="uploader" class="wu-example">
    <div id="thelist" class="uploader-list"></div>
    <div class="btns">
        <div id="picker">选择大文件</div>
        <button id="ctlBtn" class="btn btn-default">开始上传</button>
    </div>
</div>

<!--引入JS,jquery的js已经引入-->
<script type="text/javascript" src="static/html/bigFileUpload/assets/webuploader.js"></script>
<script type="text/javascript" src="static/html/bigFileUpload/assets/bootstrap-3.3.7-dist/js/bootstrap.js"></script>

<!--业务js文件-->
<script>
    var $btn = $(\'#ctlBtn\');
    var $thelist = $(\'#thelist\');
    var chunkSize = 5 * 1024 * 1024;

    // HOOK 这个必须要再uploader实例化前面
    WebUploader.Uploader.register({
        \'before-send-file\': \'beforeSendFile\',
        \'before-send\': \'beforeSend\'
    }, {
        beforeSendFile: function (file) {
            console.log("beforeSendFile");
            // Deferred对象在钩子回掉函数中经常要用到,用来处理需要等待的异步操作。
            var task = new $.Deferred();
            // 根据文件内容来查询MD5
            uploader.md5File(file).progress(function (percentage) {   // 及时显示进度
                console.log(\'计算md5进度:\', percentage);
                getProgressBar(file, percentage, "MD5", "MD5");
            }).then(function (val) { // 完成
                console.log(\'md5 result:\', val);
                file.md5 = val;
                // 模拟用户id
                // file.uid = new Date().getTime() + "_" + Math.random() * 100;
                file.uid = WebUploader.Base.guid();
                // 进行md5判断
                $.post("break/checkFileMd5", {uid: file.uid, md5: file.md5,"Authorization": localStorage.token},
                        function (data) {
                            console.log(data.status);
                            var status = data.status.value;
                            task.resolve();
                            if (status == 101) {
                                // 文件不存在,那就正常流程
                            } else if (status == 100) {
                                // 忽略上传过程,直接标识上传成功;
                                uploader.skipFile(file);
                                file.pass = true;
                            } else if (status == 102) {
                                // 部分已经上传到服务器了,但是差几个模块。
                                file.missChunks = data.data;
                            }
                        });
            });
            return $.when(task);
        },
        beforeSend: function (block) {
            console.log("block")
            var task = new $.Deferred();
            var file = block.file;
            var missChunks = file.missChunks;
            var blockChunk = block.chunk;
            console.log("当前分块:" + blockChunk);
            console.log("missChunks:" + missChunks);
            if (missChunks !== null && missChunks !== undefined && missChunks !== \'\') {
                var flag = true;
                for (var i = 0; i < missChunks.length; i++) {
                    if (blockChunk == missChunks[i]) {
                        console.log(file.name + ":" + blockChunk + ":还没上传,现在上传去吧。");
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    task.reject();
                } else {
                    task.resolve();
                }
            } else {
                task.resolve();
            }
            return $.when(task);
        }
    });

    // 实例化
    var uploader = WebUploader.create({
        pick: {
            id: \'#picker\',
            label: \'点击选择文件\'
        },
        formData: {
            uid: 0,
            md5: \'\',
            chunkSize: chunkSize,
            "Authorization": localStorage.token
        },
        //dnd: \'#dndArea\',
        //paste: \'#uploader\',
        swf: \'static/html/bigFileUpload/assets/Uploader.swf\',
        chunked: true,
        chunkSize: chunkSize, // 字节 1M分块
        threads: 3,
        server: \'break/fileUpload\',
        auto: false,

        // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
        disableGlobalDnd: true,
        fileNumLimit: 1024,
        fileSizeLimit: 1024 * 1024 * 1024,    // 200 M
        fileSingleSizeLimit: 1024 * 1024 * 1024    // 50 M
    });

    // 当有文件被添加进队列的时候
    uploader.on(\'fileQueued\', function (file) {
        console.log("fileQueued");
        $thelist.append(\'<div id="\' + file.id + \'" class="item">\' +
                \'<h4 class="info">\' + file.name + \'</h4>\' +
                \'<p class="state">等待上传...</p>\' +
                \'</div>\');
    });

    //当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
    uploader.onUploadBeforeSend = function (obj, data) {
        console.log("onUploadBeforeSend");
        var file = obj.file;
        data.md5 = file.md5 || \'\';
        data.uid = file.uid;
    };
    // 上传中
    uploader.on(\'uploadProgress\', function (file, percentage) {
        getProgressBar(file, percentage, "FILE", "上传进度");
    });
    // 上传返回结果
    uploader.on(\'uploadSuccess\', function (file) {
        var text = \'已上传\';
        if (file.pass) {
            text = "文件妙传功能,文件已上传。"
        }
        $(\'#\' + file.id).find(\'p.state\').text(text);
    });
    uploader.on(\'uploadError\', function (file) {
        $(\'#\' + file.id).find(\'p.state\').text(\'上传出错\');
    });
    uploader.on(\'uploadComplete\', function (file) {
        // 隐藏进度条
        fadeOutProgress(file, \'MD5\');
        fadeOutProgress(file, \'FILE\');
    });
    // 文件上传
    $btn.on(\'click\', function () {
        console.log("上传...");
        uploader.upload();
        console.log("上传成功");
    });

    /**
     *  生成进度条封装方法
     * @param file 文件
     * @param percentage 进度值
     * @param id_Prefix id前缀
     * @param titleName 标题名
     */
    function getProgressBar(file, percentage, id_Prefix, titleName) {
        var $li = $(\'#\' + file.id), $percent = $li.find(\'#\' + id_Prefix + \'-progress-bar\');
        // 避免重复创建
        if (!$percent.length) {
            $percent = $(\'<div id="\' + id_Prefix + \'-progress" class="progress progress-striped active">\' +
                    \'<div id="\' + id_Prefix + \'-progress-bar" class="progress-bar" role="progressbar" style="width: 0%">\' +
                    \'</div>\' +
                    \'</div>\'
            ).appendTo($li).find(\'#\' + id_Prefix + \'-progress-bar\');
        }
        var progressPercentage = percentage * 100 + \'%\';
        $percent.css(\'width\', progressPercentage);
        $percent.html(titleName + \':\' + progressPercentage);
    }

    /**
     * 隐藏进度条
     * @param file 文件对象
     * @param id_Prefix id前缀
     */
    function fadeOutProgress(file, id_Prefix) {
        $(\'#\' + file.id).find(\'#\' + id_Prefix + \'-progress\').fadeOut();
    }
</script>

 

   2.API接口

package org.triber.portal.breakPoint;

import org.apache.commons.io.FileUtils;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import以上是关于webUploader实现大文件分片,断点续传的主要内容,如果未能解决你的问题,请参考以下文章

webuploader+web如何实现分片+断点续传

jsp利用webuploader实现超大文件分片上传断点续传

webuploader+php如何实现分片+断点续传

webuploader 大文件分片上传处理

利用webuploader实现超大文件分片上传断点续传

大文件断点续传插件webupload插件