今天面试的时候被面试官问到,假如说一个很大的文件让你去上传你该如何去做呢,当时我就懵了,只记得有一个技术叫分片上传,但是具体怎么实现的我也没有去自己实现,经过后面的学习,就来分享一下分片上传这个功能的实现吧。
1.首先先写一个上传文件的入口,以及上传完文件的一个图片展示(这里我就上传图片了,比较直观一点)
<input type="file" @change="change" multiple />
<img id="slicedImg" style="display: none; height: 200px; width: 300px" />
2.根据上传图片的change事件去获取当前的文件内容进行切片,我这里的话只是对一张图片进行切片所以用的file.slice(0, 1024 * 200),对图片进行了200kb的切割。
const files = (e.target as HTMLInputElement).files as FileList;
const { size, name, type } = files[0];
const chunkSize = 10 * 1024;
let index = 0;
let start = 0;
const file = files[0];
const img: any = document.getElementById("slicedImg");
const fileOne = file.slice(0, 1024 * 200);
3.接着我用了FileReader对象,当这个FileReader函数对象读取完图片后,就会调用reader.onload回调函数,将我们的图片展示出来
var reader = new FileReader();
reader.onload = function (e) {
img.src = e.target?.result;
img.style.display = "block";
};
reader.readAsDataURL(fileOne);
4.让我们看一下完整的代码
const change = (e: Event) => {
const files = (e.target as HTMLInputElement).files as FileList;
const { size, name, type } = files[0];
const chunkSize = 10 * 1024;
let index = 0;
let start = 0;
const file = files[0];
const img: any = document.getElementById("slicedImg");
const fileOne = file.slice(0, 1024 * 200);
var reader = new FileReader();
reader.onload = function (e) {
img.src = e.target?.result;
img.style.display = "block";
};
reader.readAsDataURL(fileOne);
};
5.看一下效果图
上面这张图片就是我们截取200kb后的图片
6.接下来我们想要将截取的片段全部上传,只需要遍历截取,然后在调用接口,就完成了分片上传功能,下面我就放入遍历代码
const change = (e: Event) => {
const files = (e.target as HTMLInputElement).files as FileList;
const { size, name, type } = files[0];
const chunkSize = 10 * 1024;
let index = 0;
let start = 0;
const file = files[0];
reader.readAsDataURL(fileOne);
while (start < size) {
let blob = null;
if (start + chunkSize > size) {
blob = file.slice(start,size);
} else {
blob = file.slice(start, start + chunkSize);
}
start += chunkSize;
let blobFile = new File([blob], name);
let formData = new FormData();
formData.append('file', blobFile);
formData.append('index', String(index));
index++;
...//这就是将formData放入接口中传入就好
}
};