const BLOB_SIZE = 2 * 1024 * 1024; // 2MB/片
async function uploadLargeFile(file) {
const totalChunks = Math.ceil(file.size / BLOB_SIZE);
for (let i = 0; i < totalChunks; i++) {
const start = i * BLOB_SIZE;
const end = Math.min(start + BLOB_SIZE, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('file', chunk);
formData.append('chunkIndex', i);
formData.append('totalChunks', totalChunks);
formData.append('fileName', file.name);
// 同步發送保證順序,或用 Promise.all 併發配合後端校驗
await sendChunk(formData);
updateProgress((i + 1) / totalChunks * 100);
}
await mergeChunks(file.name); // 通知後端合併
}
function sendChunk(fd) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.php', true); // 異步
xhr.onload = () => xhr.status === 200 ? resolve() : reject(xhr.statusText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send(fd);
});
}
直接使用成熟庫:Resumable.js、Uppy、WebUploader,已處理並發控制、斷點記憶、錯誤重試、UI 組件等細節。