一、大文件的分片上传
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chunked File Upload</title>
</head>
<body>
<input type="file" id="fileInput">
<button onclick="uploadFile()">Upload</button>
<script>
const chunkSize = 1024 * 1024; // 每个分片大小为1MB
let file;
let chunks = [];
document.getElementById('fileInput').addEventListener('change', function(event) {
file = event.target.files[0];
});
function uploadFile() {
if (!file) {
console.error('Please select a file.');
return;
}
let fileSize = file.size;
let numberOfChunks = Math.ceil(fileSize / chunkSize);
for (let i = 0; i < numberOfChunks; i++) {
let start = i * chunkSize;
let end = Math.min(fileSize, start + chunkSize);
let chunk = file.slice(start, end);
chunks.push(chunk);
}
// 模拟分片上传
uploadChunks(chunks);
}
function uploadChunks(chunks) {
let currentChunk = 0;
function uploadNextChunk() {
if (currentChunk < chunks.length) {
let formData = new FormData();
formData.append('chunk', chunks[currentChunk]);
formData.append('totalChunks', chunks.length);
formData.append('chunkIndex', currentChunk);
// 发送分片数据给后端进行处理
// 这里可以使用fetch或者其他Ajax库发送请求
currentChunk++;
// 模拟延迟,实际应用中需要根据网络情况设置合适的延迟
setTimeout(uploadNextChunk, 1000);
} else {
console.log('File upload complete!');
}
}
uploadNextChunk();
}
</script>
</body>
</html>
在这个示例中,首先通过<input type="file">
元素让用户选择要上传的文件,然后在点击“Upload”按钮时触发uploadFile()
函数,该函数会将文件按照指定大小切分成多个分片,并调用uploadChunks()
函数模拟分片上传过程。
二、大文件分片上传结合断点上传
前端将文件分片并逐个上传到后端,同时后端需要保存已上传的分片信息,以便在中断后能够恢复上传。以下是一个简单的示例,展示如何实现大文件的分片上传和断点上传:
前端代码示例(使用Fetch API)
const chunkSize = 1024 * 1024; // 每个分片大小为1MB
let file;
let chunks = [];
document.getElementById('fileInput').addEventListener('change', function(event) {
file = event.target.files[0];
});
function uploadChunk(chunkData, totalChunks, chunkIndex) {
const formData = new FormData();
formData.append('chunk', chunkData);
formData.append('totalChunks', totalChunks);
formData.append('chunkIndex', chunkIndex);
fetch('https://api.example.com/uploadChunk', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Chunk uploaded successfully:', data);
if (chunkIndex < chunks.length - 1) {
uploadNextChunk(chunkIndex + 1);
} else {
console.log('File upload complete!');
}
})
.catch(error => {
console.error('There was a problem with the upload operation: ', error);
});
}
function uploadNextChunk(chunkIndex) {
uploadChunk(chunks[chunkIndex], chunks.length, chunkIndex);
}
function uploadFile() {
if (!file) {
console.error('Please select a file.');
return;
}
let fileSize = file.size;
let numberOfChunks = Math.ceil(fileSize / chunkSize);
for (let i = 0; i < numberOfChunks; i++) {
let start = i * chunkSize;
let end = Math.min(fileSize, start + chunkSize);
let chunk = file.slice(start, end);
chunks.push(chunk);
}
uploadNextChunk(0); // 开始上传第一个分片
}
在上述前端代码中,uploadFile()
函数会将文件分片后逐个上传到后端,如果其中某个分片上传失败,可以通过保存当前上传进度信息,再次发起上传请求来实现断点续传。
后端处理示例(基于Node.js和Express)
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const app = express();
const upload = multer({ dest: 'uploads/' });
app.post('/uploadChunk', upload.single('chunk'), (req, res) => {
const chunk = req.file;
const totalChunks = parseInt(req.body.totalChunks);
const chunkIndex = parseInt(req.body.chunkIndex);
// 保存分片文件
fs.rename(chunk.path, `uploads/chunk_${chunkIndex}`, err => {
if (err) {
console.error(err);
res.status(500).json({ message: 'Error saving chunk' });
} else {
res.json({ message: 'Chunk uploaded successfully' });
}
});
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
以上是一个简单的示例代码,用于演示在前端实现大文件的分片上传和断点上传功能。在实际项目中,需要根据具体需求和后端服务的不同进行适当调整和扩展。