大文件上传通常需要分片处理、断点续传等技术来提高上传效率和可靠性。以下是一个简单的JavaScript示例,展示如何实现大文件的分片上传和断点续传:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>大文件上传</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.24.0/axios.min.js"></script>
</head>
<body>
<input type="file" id="fileInput" />
<button id="uploadBtn">上传</button>
<progress id="progressBar" value="0" max="100"></progress>
<script>
// 请求基准地址
axios.defaults.baseURL = 'http://localhost:3000';
// 选中的文件
var file = null;
// 选择文件
document.getElementById('fileInput').onchange = function(event) {
file = event.target.files[0];
};
// 开始上传
document.getElementById('uploadBtn').onclick = async function() {
if (!file) return;
const chunkSize = 10 * 1024 * 1024; // 10MB 切片大小
const chunks = fileToChunks(file, chunkSize);
const chunkHashes = await getChunksHashes(chunks);
const uploadedChunks = new Set(JSON.parse(localStorage.getItem(file.name)) || []);
for (let i = 0; i < chunks.length; i++) {
if (uploadedChunks.has(i)) {
console.log(`Chunk ${i} 已经上传`);
continue;
}
const formData = new FormData();
formData.append('chunk', chunks[i]);
formData.append('hash', chunkHashes[i]);
formData.append('index', i);
formData.append('filename', file.name);
try {
const response = await axios.post('/upload', formData);
console.log(`Chunk ${i} 上传成功`);
uploadedChunks.add(i);
} catch (error) {
console.error(`Chunk ${i} 上传失败`, error);
}
}
await axios.get('/merge', { params: { filename: file.name } });
console.log('上传完成');
};
function fileToChunks(file, size) {
const chunks = [];
for (let start = 0; start < file.size; start += size) {
const chunk = file.slice(start, start + size);
chunks.push({ hash: Date.now(), chunk: chunk });
}
return chunks;
}
async function getChunksHashes(chunks) {
const hashes = [];
for (const chunk of chunks) {
const hash = await new Promise((resolve) => {
const reader = new FileReader();
reader.onload = (event) => {
resolve(spark.end(event.target.result));
};
reader.readAsArrayBuffer(chunk.chunk);
});
hashes.push(hash);
}
return hashes;
}
</script>
</body>
</html>
代码解析:
文件选择与切片:
- 用户选择文件后,代码将文件分片,每个分片大小为10MB。
fileToChunks
函数负责将文件分割成多个分片,并为每个分片生成一个唯一的哈希值。
上传分片:
- 使用
axios
库将每个分片上传到服务器。 - 每个分片上传成功后,将分片索引记录到
localStorage
中,以便断点续传。
- 使用
合并分片:
- 所有分片上传完成后,通过GET请求通知服务器合并分片。
进度展示:
- 使用
<progress>
元素实时展示上传进度。
- 使用
进阶功能:
- 断点续传:通过
localStorage
记录已上传的分片索引,下次上传时跳过已上传的部分。 - 并发控制:可以进一步优化,限制同时上传的分片数量,避免浏览器内存溢出。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。