<! DOCTYPE html>
< html >
< head >
< meta charset="utf-8" />
< title >夜鹰教程网大文件分块上传</ title >
< style type="text/css">
* {
font-family: "微软雅黑";
margin: 0;
padding: 0;
}
.container {
padding-top: 10px;
padding-left: 10px;
}
.container input {
width: 120px;
height: 30px;
background-color: blue;
color: white;
border: 0;
line-height: 30px;
border-radius: 5px;
margin-right: 5px;
outline: none;
cursor: pointer;
}
#filelist {
width: 800px;
border: solid 1px #eee;
border-collapse: collapse;
margin: 10px;
}
#filelist td {
border-bottom: solid 1px #eee;
height: 30px;
font-size: 12px;
/*line-height:30px ;*/
padding: 0 3px;
}
.filename {
width: 200px;
text-align: center;
}
.filestatus {
width: 100px;
text-align: center;
}
.fileprogress {
text-align: center;
}
.domprogress {
width: 320px;
}
.domsize {
display: block;
}
#tdmsg {
text-align: center;
}
#fileselect {
display: none;
}
span.domtime {
display:block;
}
</ style >
</ head >
< body >
< div class="container">
< input type="file" name="fileselect" id="fileselect" value="" multiple/>
< input type="button" id="btnselect" value="选择上传的文件" />
< input type="button" id="btnupload" value="开始上传" />
</ div >
< table cellspacing="0" cellpadding="0" id="filelist">
< tr >
< td class="filename">文件名</ td >
< td class="fileprogress">进度</ td >
< td class="filestatus">状态</ td >
</ tr >
<!--<tr><td>人民的名义.avi </td><td><progress value="10" max="100" class="domprogress"></progress><span class="dompercent">10%</span><span class="domsize">0/1.86GB</span></td><td class="filestatus"><span class="domstatus">排队中</span></td></tr>-->
< tr id="trmsg">
< td colspan="3" id="tdmsg">请选择要上传的文件! 技术支持QQ:1416759661</ td >
</ tr >
</ table >
< script src="js/jquery-1.11.0.js" type="text/javascript" charset="utf-8"></ script >
< script src="js/spark-md5.js" type="text/javascript" charset="utf-8"></ script >
< script type="text/javascript">
$("#btnselect").click(function() {
$("#fileselect").click();
});
$("#fileselect").change(function() {
var files = this.files;
if(files.length > 0) {
$("#trmsg").remove();
$(files).each(function(index, item) {
console.log(index, item);
var filesize = 0;
if((item.size / 1024 / 1024 / 1024) >= 1) {
filesize = (item.size / 1024 / 1024 / 1024).toFixed(2) + "GB"; // b=>kb=>mb=>gb
} else if((item.size / 1024 / 1024 / 1024) < 1 && (item.size / 1024 / 1024) >= 1) {
filesize = (item.size / 1024 / 1024).toFixed(2) + "MB";
} else if((item.size / 1024 / 1024) < 1 && (item.size / 1024) >= 1) {
filesize = (item.size / 1024).toFixed(2) + "KB";
} else {
filesize = item.size + "B";
}
var htmlstr = '< tr >< td >' + item.name + '</ td >< td >< progress value="0" max="100" class="domprogress"></ progress >< span class="dompercent"> 0/'+filesize+'</ span >< span class="domtime">总共耗时:0 秒</ span ></ td >< td class="filestatus">< span class="domstatus">排队中</ span ></ td ></ tr >';
$("#filelist").append(htmlstr);
});
}
});
$("#btnupload").click(function() {
var files = $("#fileselect")[0].files;
$(files).each(function (index, item) {
yyupload(files[index], $("span.domstatus").eq(index), $("span.dompercent").eq(index), $(".domprogress").eq(index), $("span.domtime").eq(index));
});
});
//文件上传
function yyupload(file, dommsg, dompercentmb, domprogress, domtime, fn) {
var startTime = new Date();
//获取文件的md5字符串,用于标识文件的唯一性。
calculate(file);
//获取文件的加密字符串
function calculate(file) {
var fileReader = new FileReader();
var chunkSize = 1024 * 1024 * 5; //每次读取5MB
var chunksCount = Math.ceil(file.size / chunkSize); //回大于参数x的最小整数 8=》8 8.4=》9 8.5=》9 -8.5=》-8
var currentChunk = 0; //当前块的索引
var spark = new SparkMD5();
fileReader.onload = function(e) {
console.log((currentChunk + 1) + "/" + chunksCount)
dommsg.text("正在检查文件: " + (currentChunk + 1) + "/" + chunksCount);
spark.appendBinary(e.target.result); // 添加二进制字符串
currentChunk++;
if(currentChunk < chunksCount ) {
loadNext();
} else {
var md5value = spark.end();
console.log("文件加密结束,密钥为:" + md5value);
checkfile(md5value, file); //检查服务器是否存在该文件,存在就从断点继续上传
}
};
function loadNext() {
var start = currentChunk * chunkSize; //计算读取开始位置
var end = start + chunkSize >= file.size ? file.size : start + chunkSize; //计算读取结束位置
fileReader.readAsBinaryString(file.slice(start, end)); //读取为二进制字符串
};
loadNext();
}
var repeatcount = 0;
//检查文件是否已经存在
function checkfile(md5value, file) {
var fd = new FormData();
fd.append('rquesttype', "chekcfile");
fd.append('filename', file.name);
fd.append('md5value', md5value);
var xhr = new XMLHttpRequest();
xhr.open('post', 'FileUpoload.ashx', true);
xhr.onreadystatechange = function(res) {
if(xhr.readyState == 4 && xhr.status == 200) {
var jsonobj = JSON.parse(xhr.responseText); //可以将json字符串转换成json对象 //JSON.stringify(jsonobj); //可以将json对象转换成json对符串
console.log("继续上传的位置:" + jsonobj.startindex);
switch(jsonobj.flag) {
case "0":
doUpload(md5value, file, 0);
break;
case "1":
doUpload(md5value, file, parseInt(jsonobj.startindex));
break;
case "2":
secondUpload(file);
break;
}
repeatcount = 0;
} else if(xhr.status == 500) {
setTimeout(function() {
if(repeatcount < 3 ) {
checkfile(md5value, file);
}
repeatcount++;
}, 3000);
}
}
//开始发送
xhr.send(fd);
}
//实现秒传功能
function secondUpload(file)
{
var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
domtime.text("耗时" + timerange + "秒");
//显示结果进度
var percent =100;
dommsg.text(percent.toFixed(2) + "%");
domprogress.val(percent);
var total = file.size;
if (total > 1024 * 1024 * 1024) {
dompercentmb.text((total / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
} else if (total > 1024 * 1024) {
dompercentmb.text((total / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
} else if (total > 1024 && total < 1024 * 1024) {
dompercentmb.text((total / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
} else {
dompercentmb.text((total).toFixed(2) + "B/" + (total).toFixed(2) + "B");
}
}
//上传文件
function doUpload(md5value,file,startindex) {
var reader = new FileReader();//新建一个读文件的对象
var step = 1024 * 200; //每次读取文件大小 200KB
var cuLoaded = startindex; //当前已经读取总数
var total = file.size;//文件的总大小
//读取一段成功
reader.onload = function (e) {
//处理读取的结果
var result = reader.result; //本次读取的数据
var loaded = e.loaded; //本次读取的数据长度
uploadFile(result, cuLoaded, function () { //将分段数据上传到服务器
cuLoaded += loaded; //如果没有读完,继续
var timerange = (new Date().getTime() - startTime.getTime()) / 1000;
if (total > 1024 * 1024 * 1024) {
dompercentmb.text((cuLoaded / 1024 / 1024 / 1024).toFixed(2) + "GB/" + (total / 1024 / 1024 / 1024).toFixed(2) + "GB");
} else if (total > 1024 * 1024) {
dompercentmb.text((cuLoaded / 1024 / 1024).toFixed(2) + "MB/" + (total / 1024 / 1024).toFixed(2) + "MB");
} else if (total > 1024 && total < 1024 * 1024) {
dompercentmb.text((cuLoaded / 1024).toFixed(2) + "KB/" + (total / 1024).toFixed(2) + "KB");
} else {
dompercentmb.text((cuLoaded).toFixed(2) + "B/" + (total).toFixed(2) + "B");
}
domtime.text("耗时" + timerange + "秒");
if (cuLoaded < total) {
readBlob(cuLoaded);
} else {
console.log('总共用时:' + timerange);
cuLoaded = total;
sendfinish(); //告知服务器上传完毕
domtime.text("上传完成,总共耗时" + timerange + "秒");
}
//显示结果进度
var percent = (cuLoaded/total) * 100;
dommsg.text(percent.toFixed(2) + "%");
domprogress.val(percent);
});
}
var k = 0;
function sendfinish() {
var fd = new FormData();
fd.append('rquesttype', "finishupload");
fd.append('filename', file.name);
fd.append('md5value', md5value);
fd.append('totalsize', file.size);
var xhr = new XMLHttpRequest();
xhr.open('post', 'FileUpoload.ashx', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (fn) {
fn(); //如果上传成功,继续上传下一个文件
}
k = 0;
} else if (xhr.status == 500) {
setTimeout(function () {
if (k < 3) {
sendfinish();
//上传完毕的前端处理
}
k++
}, 3000);
}
}
//开始发送
xhr.send(fd);
}
var m = 0;
//关键代码上传到服务器
function uploadFile(result, startIndex, onSuccess) {
var blob = new Blob([result]);
//提交到服务器
var fd = new FormData();
fd.append('file', blob);
fd.append('rquesttype',"uploadblob");
fd.append('filename', file.name);
fd.append('md5value', md5value);
fd.append('loaded', startIndex);
var xhr = new XMLHttpRequest();
xhr.open('post', 'FileUpoload.ashx', true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
m = 0;
if (onSuccess)
onSuccess();
} else if (xhr.status == 500) {
setTimeout(function () {
if (m < 3) {
containue();
m++;
}
}, 1000);
}
}
//开始发送
xhr.send(fd);
}
//指定开始位置,分块读取文件
function readBlob(start) {
//指定开始位置和结束位置读取文件
var blob = file.slice(start, start + step); //读取开始位置和结束位置的文件
reader.readAsArrayBuffer(blob); //读取切割好的文件块
}
//继续
function containue() {
readBlob(cuLoaded);
}
readBlob(cuLoaded);
}
}
</script>
</ body >
</ html >
|