(此功能前端共需调用3个接口,分别为简称作 A / B / C) 1,获取文件信息:使用HTML5的原生上传input,选择文件后,获取文件的所有信息(文件名、文件总字节数等) 2,计算总切片:跟后台约定好单个切片大小,比如1M/片,计算文件总大小/单个切片大小=总切片数 3,计算文件MD5和每个切片的MD5:引用spark-md5.min.js来生成MD5,此js的调用可以获取文件MD5、切片的MD5和切片的数据 4,调用A接口查询从第几个切片开始上传:需要向后台传入的关键参数是文件名、文件总大小、文件的MD5 5,获取到初始上传切片位置,正式开始分片上传到服务器:从A接口获取到切片位置后,调用接口B,将切片的MD5和切片数据传给后台,此后循环调用接口B,直到最后一切片上传结束 6,所有切片上传结束后,调用接口C将文件存库复制代码
详细代码展示:
HTML:
复制代码
获取文件信息:
function handleFile() { var fileInputs = $("input[name='myfiles']")[0]; //获取input里的文件信息 //切割文件的每条内容分别存放 var name = fileInputs.files[0].name, //文件名 size = fileInputs.files[0].size, //文件总字节 type = fileInputs.files[0].type, //文件类型 (此功能暂且用不到) shardSize = 1024 * 1024, // 每个切片的总字节数,比如此时以1M为一个分片 shardCount = Math.ceil(size / shardSize); //总片数}复制代码
计算整个文件的MD5:(前提是引入了spark.js,下载地址: )
var singleFileData = new Array(); //初始空数组,储存所有的切片数据var fileReader = new FileReader(), blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice, chunkSize = shardSize , //单个切片的总字节数 chunks = shardCount, //总片数 currentChunk = 0;var spark = new SparkMD5.ArrayBuffer(); fileReader.onload = function (e) { //*******获取分片文件,用于计算所有切片的MD5*** for (var i = 0; i < chunks; i++) { var start = i * chunkSize, end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; var sliceFile = blobSlice.call(file, start, end); // 调用此方法,计算每个切片的MD5 getChunkMd5(sliceFile, i); } //***************************** spark.append(e.target.result); if (currentChunk < chunks) { currentChunk++; loadNext(); } else { var allFileEnd = spark.end() console.log("此值为整个切片的MD5", allFileEnd) //真实MD5值 :allFileEnd=a0ce27800ee7d948422f3fe16e898f22 // ***调用接口(1),查询从第几个切片开始上传*** // ***在此处写接口A的调用方法*** } }; function loadNext() { //计算切片的start,end,用于切割出切片的数据 var start = currentChunk * chunkSize, end = start + chunkSize >= file.size ? file.size : start + chunkSize; fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); //储存切片的数据 //判断如果singleFileData小于总切片数,则继续往数组添加切片数据 if (singleFileData.length != chunks) { singleFileData.push(blobSlice.call(file, start, end)) //将每个切片push到空数组里 } }; //调用此方法,循环获取切片数据 loadNext()复制代码