js完成文件切片上传,断点续传

思绪很简单,拿到文件,保留文件唯一性标识,切割文件,分段上传,每次上传一段,依据唯一性标识推断文件上传进度,直到文件的悉数片断上传完毕。

以下笔墨没有完全的代码,只要基础理论,伸手党绕道。

读取文件

var input = document.querySelector('input');
input.addEventListener('change', function() {
    var file = this.files[0];
});

文件唯一性

var md5code = md5(file);

文件切割

var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.addEventListener("load", function(e) {
    //每10M切割一段,这里只做一个切割演示,现实切割须要轮回切割,
    var slice = e.target.result.slice(0, 10*1024*1024);
});

h5上传一个(一片)文件

var formdata = new FormData();
formdata.append('0', slice);
//这里是有一个坑的,部份装备没法猎取文件名称,和文件范例,这个在末了给出解决方案
formdata.append('filename', file.filename);
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function() {
    //xhr.responseText
});
xhr.open('POST', '');
xhr.send(formdata);
xhr.addEventListener('progress', updateProgress);
xhr.upload.addEventListener('progress', updateProgress);

function updateProgress(event) {
    if (event.lengthComputable) {
        //进度条
    }
}

没法猎取文件范例的装备解决方案

首先在:
http://www.garykessler.net/li…

这里只给出了罕见的图片和视频的文件范例推断

function checkFileType(type, file, back) {
    /**
     * type png jpg mp4 ...
     * file input.change=> this.files[0]
     * back callback(boolean)
     */
    // http://www.garykessler.net/library/file_sigs.html
    var args = arguments;
    if (args.length != 3) {
        back(0);
    }
    var type = args[0]; // type = '(png|jpg)' , 'png'
    var file = args[1];
    var back = typeof args[2] == 'function' ? args[2] : function() {};
    if (file.type == '') {
        // 假如体系没法猎取文件范例,则读取二进制流,对二进制举行剖析文件范例
        var imgType = [
            'ff d8 ff', //jpg
            '89 50 4e', //png

            '0 0 0 14 66 74 79 70 69 73 6F 6D', //mp4
            '0 0 0 18 66 74 79 70 33 67 70 35', //mp4
            '0 0 0 0 66 74 79 70 33 67 70 35', //mp4
            '0 0 0 0 66 74 79 70 4D 53 4E 56', //mp4
            '0 0 0 0 66 74 79 70 69 73 6F 6D', //mp4

            '0 0 0 18 66 74 79 70 6D 70 34 32', //m4v
            '0 0 0 0 66 74 79 70 6D 70 34 32', //m4v

            '0 0 0 14 66 74 79 70 71 74 20 20', //mov
            '0 0 0 0 66 74 79 70 71 74 20 20', //mov
            '0 0 0 0 6D 6F 6F 76', //mov

            '4F 67 67 53 0 02', //ogg
            '1A 45 DF A3', //ogg

            '52 49 46 46 x x x x 41 56 49 20', //avi (RIFF fileSize fileType LIST)(52 49 46 46,DC 6C 57 09,41 56 49 20,4C 49 53 54)
        ];
        var typeName = [
            'jpg',
            'png',
            'mp4',
            'mp4',
            'mp4',
            'mp4',
            'mp4',
            'm4v',
            'm4v',
            'mov',
            'mov',
            'mov',
            'ogg',
            'ogg',
            'avi',
        ];
        var sliceSize = /png|jpg|jpeg/.test(type) ? 3 : 12;
        var reader = new FileReader();
        reader.readAsArrayBuffer(file);
        reader.addEventListener("load", function(e) {
            var slice = e.target.result.slice(0, sliceSize);
            reader = null;
            if (slice && slice.byteLength == sliceSize) {
                var view = new Uint8Array(slice);
                var arr = [];
                view.forEach(function(v) {
                    arr.push(v.toString(16));
                });
                view = null;
                var idx = arr.join(' ').indexOf(imgType);
                if (idx > -1) {
                    back(typeName[idx]);
                } else {
                    arr = arr.map(function(v) {
                        if (i > 3 && i < 8) {
                            return 'x';
                        }
                        return v;
                    });
                    var idx = arr.join(' ').indexOf(imgType);
                    if (idx > -1) {
                        back(typeName[idx]);
                    } else {
                        back(false);
                    }

                }
            } else {
                back(false);
            }

        });
    } else {
        var type = file.name.match(/\.(\w+)$/)[1];
        back(type);
    }
}
挪用要领
checkFileType('(mov|mp4|avi)',file,function(fileType){
    // fileType = mp4,
    // 假如file的范例不在罗列之列,则返回false
});

上面上传文件的一步,能够改成:

formdata.append('filename', md5code+'.'+fileType);

总结:有了切割上传,有了文件唯一标识信息(文件md5)断点续传只不过是背景的一个小小的推断逻辑罢了。

将来,前端,大有可为

有些小伙伴不是太清晰背景的小小的推断是怎样做的:
这里贴一张图给人人参考,本身手画,有点丑,将就下。

《js完成文件切片上传,断点续传》

后续我再画一张完全的上传流程图给更新上来。

    原文作者:jsoncode
    原文地址: https://segmentfault.com/a/1190000009448892
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞