文件切分上传
昨天有些文艺了。。。今天来点儿干货,总结一下大文件切割上传问题。
emmmmmmm......
好像直接上代码就可以了,话不多说
HTML:
<div class="wrapper">
<input id="file" type="file" onchange="window.upload()"/>
<div class="count">
<div class="current"></div>
</div>
</div>
CSS:
.wrapper{
display: flex;
flex-direction: column;
align-items: center;
}
.count{
margin-top: 20px;
width: 400px;
height: 8px;
line-height: 8px;
background-color: #eeeeee;
}
.current{
display: inline-block;
height: 8px;
background-color: #00cc00;
transition: 0.5s;
text-align: center;
font-size: 12px;
}
JAVASCRIPT:
(function(){
var start = 0, // 文件片段开始点
length = 100, // 文件片段size
end = start + length, // 文件片段结束点
count = 0, // 文件总大小(size)
blob = null, // 文件片段流
blobId = 1, // 片段ID
isLastBlob = 0, // 是否已经将所有文件都上传完成 0 :未完成, 1: 完成
formData = null, // formData实例
file = null, // 当前选择的文件
xhr =null,
pecentElement = document.querySelector('.current');
window.upload = function upload () {
file = document.querySelector('#file').files[0];
count = file.size;
up();
}
function up() {
if(start < count) {
blob = file.slice(start, end);
if(start + length > count) {
isLastBlob = 1;
}
// 创建formData将数据append 进去,最后一起send到服务端。
formData = new FormData();
formData.append('blob', blob);
formData.append('fileName', file.name);
formData.append('blobId', blobId);
formData.append('isComplate', isLastBlob);
// 写了两个方法, ajax 为ajax发送数据上传,simulateAjax 为模拟ajax上传,因为没有后端接口
// ajax(formData);
simulateAjax();
}
}
function ajax(formData){
xhr = new XMLHttpRequest();
xhr.open('xxxx/xxx', 'POST');
xhr.onload = function () {
if(xhr.status >= 200 && xhr.status < 300) {
calculatePecent();
up();
}else {
alert('upload filed!')
start = 0;
}
}
xhr.send(formData);
}
function simulateAjax() {
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(200);
//reject(500);
}, 2000)
}).then(() => {
calculatePecent();
up();
}, () => {
alert('upload filed!')
start = 0;
})
}
function calculatePecent() {
// 成功之后片段开始等于上一次结束位置, 片段结束为开始位置加上片段长度
start = end;
end = start + length;
if(start > count){
start = count;
end = count
}
// 展示进度条,代表上传了多少
pecentElement.style.width = parseInt(start / count * 100) + '%';
pecentElement.innerHTML = parseInt(start / count * 100) + '%';
}
})()
总结: 文件分段上传核心,为slice将数据流分割,这种是针对上传的文件,如果单纯上传超大文件,不看上传了多少,可以将文件分割,同时发起多个http请求,并发上传文件片段。 这边没有介绍 xhr.onprogress这个东西,是ajax 进度事件,这个也可以简单实现进度条问题,slice主要偏重文件按照一定大小顺序上传, onprogress 主要是针对上传时带宽大小,看文件上传速度,和大小,按照现在中国宽带发展情况,未来不会因为网速问题,需要分段上传文件。
有问题的同学,欢迎留言讨论。
本文作者原创,仅供学习交流使用,转载需注明出处。