1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| class FileUploader { constructor(file, chunkSize = 10 * 1024 * 1024) { this.file = file; this.chunkSize = chunkSize; this.chunks = Math.ceil(file.size / chunkSize); this.uploadedChunks = 0; }
async upload(url) { const fileId = this.generateFileId();
for (let i = 0; i < this.chunks; i++) { const start = i * this.chunkSize; const end = Math.min(start + this.chunkSize, this.file.size); const chunk = this.file.slice(start, end);
await this.uploadChunk(url, fileId, i, chunk); this.uploadedChunks++;
console.log(`上传进度: ${((this.uploadedChunks / this.chunks) * 100).toFixed(2)}%`); }
await this.mergeChunks(url, fileId);
return fileId; }
uploadChunk(url, fileId, chunkIndex, chunk) { const formData = new FormData(); formData.append('fileId', fileId); formData.append('chunkIndex', chunkIndex); formData.append('totalChunks', this.chunks); formData.append('chunk', chunk);
return axios.post(url + '/chunk', formData, { headers: { 'Content-Type': 'multipart/form-data' }, timeout: 60000 }); }
mergeChunks(url, fileId) { return axios.post(url + '/merge', { fileId: fileId, fileName: this.file.name, totalChunks: this.chunks }); }
generateFileId() { return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } }
const fileInput = document.getElementById('fileInput'); fileInput.addEventListener('change', async (e) => { const file = e.target.files[0]; const uploader = new FileUploader(file);
try { const fileId = await uploader.upload('/api/upload'); console.log('上传成功:', fileId); } catch (error) { console.error('上传失败:', error); } });
|