针对大文件的上传,需要做额外的处理,否则可能会遇到如下问题:. W* R% ^9 B+ s5 I1 _ r
- 文件过大,超出服务端的请求大小限制(如SpringMVC,默认文件上传最大1MB)。
- 请求的时间过长,请求超时。
- 客户端网络不好的话,容易传输中断,必须整个文件重传。
9 q3 X6 c" }7 z; ~7 E 可以用分片上传的方式来解决。
+ P# {# A& r" t3 o) q' P8 d7 b M$ h一、前端处理1 I G$ c5 W- F8 X3 u; T Y: E$ p
大文件分片上传,是需要前端和后端配合操作的。整体流程是:前端将大文件进行分片,例如一个50MB的文件,分成10片,每个片5MB。然后发10个HTTP请求,将这10个分片数据发送给后端,后端根据分片的下标和Size来往磁盘文件的不同位置写入分片数据,10个分片全部写完后即得到一个完整的文件。
c7 J5 k7 q8 d) A+ c, E) d. n
2 @ s7 _2 a/ c- d- e1 Z5 o
<script>
const sliceSize = 5 * 1024 * 1024; // 每个文件切片大小定为5MB
//发送请求
function upload() {
const blob = document.getElementById("file").files[0];
const fileSize = blob.size;// 文件大小
const fileName = blob.name;// 文件名
//计算文件切片总数
const totalSlice = Math.ceil(fileSize / sliceSize);
// 循环上传
for (let i = 1; i <= totalSlice; i++) {
let chunk;
if (i == totalSlice) {
// 最后一片
chunk = blob.slice((i - 1) * sliceSize, fileSize - 1);//切割文件
} else {
chunk = blob.slice((i - 1) * sliceSize, i * sliceSize);
}
const formData = new FormData();
formData.append("file", chunk);
formData.append("md5", md5(blob));
formData.append("name", fileName);
formData.append("size", fileSize);
formData.append("chunks", totalSlice);
formData.append("chunk", i);
$.ajax({
url: 'http://localhost:8080/chunk/upload',
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false,
async: false
});
}
}
</script> Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
: E6 `* A0 {2 W7 ^9 ?9 I# i; R Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。# W0 b9 K5 l+ g4 [) C/ `, k" c% C
Blob.size 表示 Blob 对象中所包含数据的大小(字节)。
8 d- R& S3 Z1 A3 r4 H5 X Blob.slice(start, end) 返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。- r* G, u$ X! x# S% w; F
文件进行 MD5 加密 什么意思,做什么用?确保完整性:你将文件生成了MD5摘要,传输文件和MD5码给接收端,接收端接收文件后可以对文件生成MD5码然后与接收到的MD5码对比校验确保文件是完整的而且中途没有被修改。" Q& j; c2 `9 d; t
二、后端处理) H4 H9 \5 b4 ?% b5 q7 E* o1 F& N1 p
后端接收到分片数据后,要根据分片的下标和分片的大小来往文件的指定位置写入分片数据。例如:分片大小为1MB,第一个分片就要往文件的第0个字节开始,写入1048576字节的数据。第二个分片就要往文件的第1048576个字节开始,写入1048576字节的数据,以此类推。待所有的分片数据全部写入完成后,即得到一个完整的文件。% B( g2 C4 r7 e" r) x( g2 @, o( t
|