代码拉取完成,页面将自动刷新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="./bootstrap/bootstrap-theme.min.css" />
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrap {
width: 100px;
height: 40px;
background-color: red;
text-align: center
}
.wrap p {
width: 100%;
height: 100%;
line-height: 2;
text-align: center;
}
#file {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 40px;
display: block;
opacity: 0;
}
.progress {
position: relative;
}
.progress-bar {
transition: width .3s ease
}
.progress .value {
position: absolute;
color: #FF9800;
left: 50%;
}
.container {
width: 500px;
}
.row {
border-bottom: 1px solid gray;
padding: 10px;
}
.hidden {
display: none;
}
.mrb20 {
margin: 20px 0;
}
</style>
<title>上传文件</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 mrb20">点击按钮开始上传文件</div>
<div class="col-md-8">
<div class="wrap btn btn-default">
<input type="file" id="file" />
<p>上传文件</p>
</div>
</div>
</div>
<div class="row" id="process1" style="display: none">
<div class="col-md-4">校验文件进度</div>
<div class="col-md-8">
<div class="progress">
<div id="checkProcessStyle" class="progress-bar" style="width:0%"></div>
<p id="checkProcessValue" class="value">0%</p>
</div>
</div>
</div>
<div class="row" id="process2" style="display: none">
<div class="col-md-4">上传文件进度</div>
<div class="col-md-8">
<div class="progress">
<div id="uploadProcessStyle" class="progress-bar" style="width:0%"></div>
<p id="uploadProcessValue" class="value">0%</p>
</div>
</div>
</div>
</div>
<script src="./lib/jquery-1.10.2.min.js"></script>
<script src="./bootstrap/bootstrap.min.js"></script>
<script src="./lib/spark-md5.min.js"></script>
<script>
let baseUrl = 'http://localhost:5000'
let chunkSize = 5 * 1024 * 1024
let fileSize = 0
let file = null
let hasUploaded = 0
let chunks = 0
// spark = new SparkMD5.ArrayBuffer()
$("#file").on('change', function () {
file = this.files[0]
fileSize = file.size;
responseChange(file)
})
// 0.响应点击
async function responseChange(file) {
// 第一步:按照 修改时间+文件名称+最后修改时间-->MD5
// 显示文件校验进度
$("#process1").slideDown(200)
// 开始校验
let fileMd5Value = await md5File(file)
// 第二步:校验文件的MD5
let result = await checkFileMD5(file.name, fileMd5Value)
// 如果文件已存在, 就秒传
if (result.file) {
alert('文件已秒传')
return
}
// let exit = false
// 显示文件上传进度
$("#process2").slideDown(200)
// 第三步:检查并上传MD5
await checkAndUploadChunk(fileMd5Value, result.chunkList)
// 第四步: 通知服务器所有分片已上传完成
notifyServer(fileMd5Value)
}
// 1.修改时间+文件名称+最后修改时间-->MD5
function md5File(file) {
return new Promise((resolve, reject) => {
var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
//chunkSize = 2097152, // Read in chunks of 2MB
chunkSize = file.size / 100,
//chunks = Math.ceil(file.size / chunkSize),
chunks = 100,
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();
fileReader.onload = function (e) {
console.log('read chunk nr', currentChunk + 1, 'of', chunks);
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
loadNext();
} else {
let cur = +(new Date())
console.log('finished loading');
// alert(spark.end() + '---' + (cur - pre)); // Compute hash
let result = spark.end()
resolve(result)
}
};
fileReader.onerror = function () {
console.warn('oops, something went wrong.');
};
function loadNext() {
var start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
$("#checkProcessStyle").css({
width: (currentChunk + 1) + '%'
})
$("#checkProcessValue").html((currentChunk + 1) + '%')
// $("#tip").html(currentChunk)
}
loadNext();
})
}
// 2.校验文件的MD5
function checkFileMD5(fileName, fileMd5Value) {
return new Promise((resolve, reject) => {
let url = baseUrl + '/check/file?fileName=' + fileName + "&fileMd5Value=" + fileMd5Value
$.getJSON(url, function (data) {
resolve(data)
})
})
}
// 3.上传chunk
async function checkAndUploadChunk(fileMd5Value, chunkList) {
chunks = Math.ceil(fileSize / chunkSize)
hasUploaded = chunkList.length
for (let i = 0; i < chunks; i++) {
let exit = chunkList.indexOf(i + "") > -1
// 如果已经存在, 则不用再上传当前块
if (!exit) {
let index = await upload(i, fileMd5Value, chunks)
hasUploaded++
let radio = Math.floor((hasUploaded / chunks) * 100)
$("#uploadProcessStyle").css({
width: radio + '%'
})
$("#uploadProcessValue").html(radio + '%')
}
}
}
// 3-2. 上传chunk
function upload(i, fileMd5Value, chunks) {
return new Promise((resolve, reject) => {
//构造一个表单,FormData是HTML5新增的
let end = (i + 1) * chunkSize >= file.size ? file.size : (i + 1) * chunkSize
let form = new FormData()
form.append("data", file.slice(i * chunkSize, end)) //file对象的slice方法用于切出文件的一部分
form.append("total", chunks) //总片数
form.append("index", i) //当前是第几片
form.append("fileMd5Value", fileMd5Value)
$.ajax({
url: baseUrl + "/upload",
type: "POST",
data: form, //刚刚构建的form数据对象
async: true, //异步
processData: false, //很重要,告诉jquery不要对form进行处理
contentType: false, //很重要,指定为false才能形成正确的Content-Type
success: function (data) {
resolve(data.desc)
}
})
})
}
// 第四步: 通知服务器所有分片已上传完成
function notifyServer(fileMd5Value) {
let url = baseUrl + '/merge?md5=' + fileMd5Value + "&fileName=" + file.name + "&size=" + file.size
$.getJSON(url, function (data) {
alert('上传成功')
})
}
function getDate() {
let d = new Date()
return d.getMinutes() + ':' + d.getSeconds() + ' ' + d.getMilliseconds()
}
</script>
</body>
</html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。