前端大文件上传和下载一般采用分片上传和下载的方式,确保上传和下载的大文件不会占用过多的带宽和服务器资源。以下是前端大文件上传和下载的详细过程:
前端大文件上传的详细过程
-
前端将文件分片,每片数据大小和数量根据实际需求决定,一般大小为1MB - 5MB,数量为10 - 100片。可以使用FileReader API将文件读取为二进制流,然后根据分片大小对二进制流进行分片。
-
上传分片的时候需要将分片信息传递给服务端,通常有两种方式:
-
将分片信息作为HTTP请求的参数,这种方式简单直接,但是如果分片数量过多,HTTP请求URL可能会过长,而且有些服务器会对URL长度有限制;
-
将分片信息放在HTTP请求的请求体中,这种方式需要使用POST方法,相对来说更加灵活,并且不会受到URL长度的限制。
-
在服务端收到分片后,通常需要先对分片进行校验,校验通过后将分片保存在服务器端的临时文件中。可以使用MD5等算法对每个分片的数据进行校验。
-
所有分片上传完毕后,服务端会将临时文件合并为完整文件,并删除临时文件。
-
上传过程中如果出现网络故障或其他原因导致上传失败,可以通过记录上传进度,从断点续传的方式重新上传。
示例1:H5文件分片上传
function chunkUpload(url, file, callback) {
const chunkSize = 1024 * 1024; // 每个分片1MB
const fileSize = file.size;
const totalChunks = Math.ceil(fileSize / chunkSize);
let currentChunk = 0;
function upload() {
const start = currentChunk * chunkSize;
const end = Math.min(start + chunkSize, fileSize);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('chunkNumber', currentChunk + 1);
formData.append('totalChunks', totalChunks);
fetch(url, {
method: 'POST',
body: formData,
}).then(response => {
if (currentChunk + 1 < totalChunks) {
currentChunk++;
upload();
} else {
callback();
}
}).catch(error => {
console.error(error);
});
}
upload();
}
示例2:jQuery文件分片上传
function chunkUpload(url, file, callback) {
const chunkSize = 1024 * 1024; // 每个分片1MB
const fileSize = file.size;
const totalChunks = Math.ceil(fileSize / chunkSize);
let currentChunk = 0;
function upload() {
const start = currentChunk * chunkSize;
const end = Math.min(start + chunkSize, fileSize);
const chunk = file.slice(start, end);
$.ajax({
url: url,
method: 'POST',
data: {
chunk: chunk,
chunkNumber: currentChunk + 1,
totalChunks: totalChunks,
},
processData: false,
contentType: false,
}).done((response) => {
if (currentChunk + 1 < totalChunks) {
currentChunk++;
upload();
} else {
callback();
}
}).fail((jqXHR, textStatus, errorThrown) => {
console.error(errorThrown);
});
}
upload();
}
前端大文件下载的详细过程
-
服务器端将文件分段,每段大小和数量根据实际需求决定,一般大小为1MB - 5MB,数量为10 - 100段。
-
前端使用XMLHttpRequest对象进行异步http请求,并设置responseType为arraybuffer。
-
前端接收到数据后,将每段数据写入文件系统或者读取到内存中进行拼接,最终形成完整的文件。
-
下载过程中如果出现网络故障或其他原因导致下载失败,可以通过记录下载进度,从断点续传的方式重新下载。
示例3:H5文件分段下载
function chunkDownload(url, fileName) {
const chunkSize = 1024 * 1024; // 分段大小为1MB
const xhr = new XMLHttpRequest();
let currentChunk = 0;
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
const blob = new Blob([xhr.response]);
const fileReader = new FileReader();
fileReader.onload = () => {
const content = new Uint8Array(fileReader.result);
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
const link = document.createElement('a');
link.setAttribute('href', URL.createObjectURL(blob));
link.setAttribute('download', fileName);
link.click();
}
};
fileReader.readAsArrayBuffer(blob);
};
xhr.onerror = (err) => {
console.error(err);
};
xhr.onprogress = (event) => {
if (event.lengthComputable) {
const percentage = Math.floor((event.loaded / event.total) * 100);
console.log(`下载进度:${percentage}%`);
}
};
xhr.send();
}
示例4:jQuery文件分段下载
function chunkDownload(url, fileName) {
const chunkSize = 1024 * 1024; // 分段大小为1MB
let currentChunk = 0;
$.ajax({
url: url,
method: 'GET',
responseType: 'arraybuffer',
processData: false,
contentType: false,
success: (res, textStatus, jqXHR) => {
const blob = new Blob([res]);
const fileReader = new FileReader();
fileReader.onload = () => {
const content = new Uint8Array(fileReader.result);
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
const link = document.createElement('a');
link.setAttribute('href', URL.createObjectURL(blob));
link.setAttribute('download', fileName);
link.click();
}
};
fileReader.readAsArrayBuffer(blob);
},
error: (jqXHR, textStatus, errorThrown) => {
console.error(errorThrown);
},
xhr: () => {
const xhr = new window.XMLHttpRequest();
xhr.onprogress = (event) => {
if (event.lengthComputable) {
const percentage = Math.floor((event.loaded / event.total) * 100);
console.log(`下载进度:${percentage}%`);
}
};
return xhr;
},
});
}
以上是前端大文件上传和下载的详细过程以及两个示例说明,开发者可以根据实际需求,选择使用不同的框架和方式进行开发。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:前端大文件上传与下载(分片上传)的详细过程 - Python技术站