<input type="file" id="largeFile">
<button onclick="startUpload()">开始上传</button>
<div id="progressBar"></div>
<script>
async function startUpload() {
const file = document.getElementById('largeFile').files[0];
if (!file) return;
// 配置参数
const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB分片
const TOTAL_CHUNKS = Math.ceil(file.size / CHUNK_SIZE);
const FILE_ID = `${file.name}-${file.size}-${Date.now()}`;
// 创建进度跟踪器
const uploadedChunks = new Set();
// 并行上传控制(最大5并发)
const parallelLimit = 5;
let currentUploads = 0;
let activeChunks = 0;
for (let chunkIndex = 0; chunkIndex < TOTAL_CHUNKS; ) {
if (currentUploads >= parallelLimit) {
await new Promise(resolve => setTimeout(resolve, 500));
continue;
}
if (uploadedChunks.has(chunkIndex)) {
chunkIndex++;
continue;
}
currentUploads++;
activeChunks++;
const start = chunkIndex * CHUNK_SIZE;
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunk = file.slice(start, end);
uploadChunk(chunk, chunkIndex, FILE_ID, TOTAL_CHUNKS, file.name)
.then(() => {
uploadedChunks.add(chunkIndex);
updateProgress(uploadedChunks.size, TOTAL_CHUNKS);
})
.catch(err => console.error(`分片${chunkIndex}失败:`, err))
.finally(() => {
currentUploads--;
activeChunks--;
});
chunkIndex++;
}
// 检查所有分片完成
const checkCompletion = setInterval(() => {
if (activeChunks === 0 && uploadedChunks.size === TOTAL_CHUNKS) {
clearInterval(checkCompletion);
completeUpload(FILE_ID, file.name);
}
}, 1000);
}
async function uploadChunk(chunk, index, fileId, total, filename) {
const formData = new FormData();
formData.append('file', chunk, filename);
formData.append('chunkIndex', index);
formData.append('totalChunks', total);
formData.append('fileId', fileId);
return fetch('/api/upload/chunk', {
method: 'POST',
body: formData
}).then(res => {
if (!res.ok) throw new Error('上传失败');
return res.json();
});
}
async function completeUpload(fileId, filename) {
return fetch('/api/upload/merge', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileId, filename })
}).then(res => {
if (res.ok) alert('上传成功!');
else alert('合并失败');
});
}
function updateProgress(done, total) {
const percent = Math.round((done / total) * 100);
document.getElementById('progressBar').innerHTML = `
<div style="width: ${percent}%; background: #4CAF50; height: 20px;">
${percent}%
</div>
`;
}
</script>
大文件分片上传
最新推荐文章于 2025-11-24 03:12:01 发布
1337

被折叠的 条评论
为什么被折叠?



