前端大文件分片上传需要将文件切割成若干个片段,然后将每个片段上传到服务器,最终在服务端将所有的片段合并成完整的文件。下面是一个前端大文件分片上传的示例:
- 将文件切割成若干个片段。
function splitFile(file, chunkSize) {
let fileSize = file.size;
let start = 0;
let chunkIndex = 0;
let chunks = [];
while (start < fileSize) {
let end = Math.min(fileSize, start + chunkSize);
let chunk = file.slice(start, end);
chunks.push({
index: chunkIndex,
start: start,
end: end,
file: chunk
});
chunkIndex++;
start = end;
}
return chunks;
}
- 上传每个片段,使用XMLHttpRequest对象上传。
function uploadChunk(url, chunk, callback) {
let xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
let formData = new FormData();
formData.append("chunkIndex", chunk.index);
formData.append("start", chunk.start);
formData.append("end", chunk.end);
formData.append("file", chunk.file);
xhr.onload = function() {
callback(xhr.status === 200);
};
xhr.send(formData);
}
- 服务端接收片段。
const express = require("express");
const app = express();
const multer = require("multer");
let storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "./uploads");
},
filename: function(req, file, callback) {
callback(null, file.originalname + "_" + req.body.chunkIndex);
}
});
let upload = multer({ storage: storage }).single("file");
app.post("/upload", function(req, res) {
upload(req, res, function(err) {
if (err) {
res.status(500).send({ message: err.message });
} else {
res.status(200).send({ message: "Uploaded successfully" });
}
});
});
app.listen(8080);
- 合并所有片段。
function mergeChunks(url, fileName, chunkCount, callback) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url + "?fileName=" + fileName + "&chunkCount=" + chunkCount, true);
xhr.onload = function() {
callback(xhr.status === 200);
};
xhr.send();
}
- 客户端在上传完所有片段后,将所有片段合并成完整的文件。
let chunkSize = 5 * 1024 * 1024; //每个片段5MB
let file = document.getElementById("file").files[0];
let chunkCount = Math.ceil(file.size / chunkSize);
let chunks = splitFile(file, chunkSize);
let uploadedCount = 0;
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
uploadChunk("/upload", chunk, function(success) {
uploadedCount++;
if (uploadedCount === chunkCount) {
mergeChunks("/merge", file.name, chunkCount, function(success) {
console.log("File upload " + (success ? "completed" : "failed"));
});
}
});
}
注意,以上代码仅供参考,不同浏览器和服务器可能会有不同的兼容性问题,实际应用时需要进行充分测试和优化。
标签:function,start,前端,xhr,let,file,分片,上传,chunk From: https://www.cnblogs.com/kitebear/p/17418216.html