html5+javaScript +python 断点续传

html :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <input type="file" id="fileUpload"/>
   <button id="uploadBtn">上传</button>
   <div id="fileNameContent"></div>
   <div id="progressContent"></div>
   <script type="text/javascript" src="{{ url_for('static',filename='js/jquery.min.js') }}"></script>
   <script type="text/javascript" src="{{ url_for('static',filename='js/fileSliceUpload.js') }}?1"></script>
   <script>
        var fileSliceObj = new FileSliceUpload({
            'fileInputElement':document.getElementById('fileUpload'),
            'fileFormats':['zip'],
            'uploadBtn' : document.getElementById('uploadBtn'),
            'dctId':'7912c86453f8476681ccae34f0ea8c6e',
            'fileNameContent' : document.getElementById('fileNameContent'),
            'progressContent' : document.getElementById('progressContent')
        })

        fileSliceObj.init();
   </script>
</body>
</html>

javascript:

function FileSliceUpload(opt) {
    //文件上传dom元素
    this.fileInputElement = opt.fileInputElement;
    //文件校验格式数组
    this.fileFormats = opt.fileFormats;
    //上传按钮
    this.uploadBtn = opt.uploadBtn;
    //任务id
    this.dctId = opt.dctId
    //进度div
    this.progressContent = opt.progressContent
    //文件名称存储区域
    this.fileNameContent = opt.fileNameContent
    //切割文件大小(字节)10M
    this.fileSliceSize = 10*1024*1024
    //当前操作file
    this.file = null;
}

/**
 * 文件上传事件
 */
FileSliceUpload.prototype.init = function () {
    var that = this;
    this.fileInputElement.onchange = function (event) {
        //获取上传文件
        that.file = this.files[0];
        //校验上传文件
        if(that.checkFileType(that)){
            //获取上传进度
            var formdata = new FormData();
            formdata.append('fileName',that.file.name);
            formdata.append('dctId',that.dctId);
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/get_slice_file_percent',false);
            xhr.onreadystatechange = function() {
              if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
                  var responseObj = JSON.parse(xhr.response);
                  if(responseObj.hasOwnProperty('alreadyFileUploadSize')){
                      that.progressContent.innerHTML = responseObj['alreadyFileUploadSize']
                  }
              }
            };
            xhr.send(formdata);
        }
    }
    this.uploadBtn.onclick = function (event) {
        if(this.innerHTML == '上传'){
            this.innerHTML == '暂停';
            //开始上传
            var progress = that.progressContent.innerHTML;
            var upProgress = 0; //已经上传的字节数
            if(progress!=''){
                upProgress = parseInt(progress); //续传赋值
            }
            that.sliceFile(that.file,upProgress,that)
        }
    }
}

/**
 * 文件上传格式校验
 */
FileSliceUpload.prototype.checkFileType = function (that) {
    var flag = true;
    var errormessage = ''
    var separator = that.file.name.lastIndexOf('.');
    var extension = that.file.name.substr(separator + 1).toLowerCase();
    if(that.fileFormats.indexOf(extension)==-1){
        errormessage = '文件格式必须是'+that.fileFormats.join(',');
        flag = false;
    }
    if(errormessage!=''){
        $('#errorform h2').html(errormessage);
        $('#errorform').modal('show');
        setTimeout(function () {
            $('#errorform').modal('hide');
        }, 1500);
    }
    return flag;
}

/**
 * 文件切割方法
 */
FileSliceUpload.prototype.sliceFile = function (arrayBuffer,currentProgress,that) {
    //每10M切割一段,这里只做一个切割演示,实际切割需要循环切割
    var len = currentProgress+this.fileSliceSize;
    var filelengh = that.fileInputElement.files[0].size;
    if(currentProgress == filelengh){
        alert('文件上传成功');
        return false;
    }
    var slice = null;
    if(len > filelengh){
        slice = arrayBuffer.slice(currentProgress, filelengh);
    }else{
        slice = arrayBuffer.slice(currentProgress, currentProgress+that.fileSliceSize);
    }
    console.log(slice);
    var formdata = new FormData();
    formdata.append('file', slice);
    //这里是有一个坑的,部分设备无法获取文件名称,和文件类型,这个在最后给出解决方案
    formdata.append('filename', that.file.name);
    formdata.append('dctId',that.dctId);
    formdata.append('currentProgress',currentProgress);
    var xhr = new XMLHttpRequest();
    xhr.addEventListener('load', function() {
        var responseObj = JSON.parse(xhr.response);
        that.progressContent.innerHTML = responseObj['alreadyFileUploadSize'];
        that.sliceFile(arrayBuffer,parseInt(responseObj['alreadyFileUploadSize']),that);
    });
    xhr.open('POST', '/upload_slice_file');
    xhr.send(formdata);
}

python 后台:

## 获取文件进度
@main.route('/get_slice_file_percent', methods=['GET', 'POST'])
def get_slice_file_percent():
    fileName = request.form.get('fileName')
    dctId = request.form.get('dctId')
    upUrl = os.path.join(os.getcwd(), 'upload_file')
    # 文件名称 用上传的文件名md5
    filename = hashlib.md5(fileName).hexdigest()[:15] + '.'
    extend_one = os.path.splitext(secure_filename(fileName))[1][1:].lower()
    extend_two = os.path.splitext(secure_filename(fileName))[0].lower()
    # 获取文件扩展名
    if extend_one in IMAGES or extend_two in IMAGES:
        if extend_one in IMAGES:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'images')
    elif extend_one in DOCUMENTS or extend_two in DOCUMENTS:
        if extend_one in DOCUMENTS:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'documents')
    elif extend_one in ARCHIVES or extend_two in ARCHIVES:
        if extend_one in ARCHIVES:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'archives')
    elif extend_one in DATA or extend_two in DATA:
        if extend_one in DATA:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'data')

    allupUrl = os.path.join(upUrl2 , dctId, filename)
    retData = {}
    if os.path.isfile(allupUrl): #继传
        alreadyFileUploadSize = os.stat(allupUrl).st_size  # 字节为单位
        retData['alreadyFileUploadSize'] = alreadyFileUploadSize
    retData['filename'] = filename
    return gen_json_response(retData)
## 大文件分片上传
@main.route('/upload_slice_file', methods=['GET', 'POST'])
def upload_slice_file():
    file = request.files.get("file")
    ## 生成file
    fileName = request.form.get('filename')
    dctId = request.form.get('dctId')
    currentProgress = long(request.form.get('currentProgress'))
    upUrl = os.path.join(os.getcwd(), 'upload_file')
    # 文件名称 用上传的文件名md5
    filename = hashlib.md5(fileName).hexdigest()[:15] + '.'
    extend_one = os.path.splitext(secure_filename(fileName))[1][1:].lower()
    extend_two = os.path.splitext(secure_filename(fileName))[0].lower()
    # 获取文件扩展名
    if extend_one in IMAGES or extend_two in IMAGES:
        if extend_one in IMAGES:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl , 'images')
    elif extend_one in DOCUMENTS or extend_two in DOCUMENTS:
        if extend_one in DOCUMENTS:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'documents')
    elif extend_one in ARCHIVES or extend_two in ARCHIVES:
        if extend_one in ARCHIVES:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'archives')
    elif extend_one in DATA or extend_two in DATA:
        if extend_one in DATA:
            filename += extend_one
        else:
            filename += extend_two
        upUrl2 = os.path.join(upUrl, 'data')
    ##upUrl3 = os.path.join(upUrl2, current_user.userId)
    ##if not os.path.isdir(upUrl3) :
        ##os.mkdir(upUrl3)
    upUrl4 = os.path.join(upUrl2, dctId)
    if not os.path.isdir(upUrl4) :
        os.mkdir(upUrl4)
    upUrl5 = os.path.join(upUrl4, filename)
    with open(upUrl5, "ab") as zip:
        ##zip.seek(currentProgress,0)
        zip.write(file.read())
    retData = {}
    retData['alreadyFileUploadSize'] = os.stat(upUrl5).st_size
    retData['filename'] = filename
    return gen_json_response(retData)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值