使用js写一个方法实现文件上传的断点续传功能
实现文件上传的断点续传功能是一个相对复杂的任务,涉及前端和后端的协同工作。在前端,你主要需要处理文件的切片、上传进度跟踪、暂停/恢复上传以及错误处理等。以下是一个简化的前端实现示例,使用原生JavaScript和XMLHttpRequest
进行文件上传。
class ChunkedUploader {
constructor(file, url, options = {}) {
this.file = file;
this.url = url;
this.chunkSize = options.chunkSize || 1024 * 1024; // 默认1MB
this.chunks = [];
this.currentChunk = 0;
this.paused = false;
this.progress = 0;
// 计算文件分片
for (let i = 0; i < Math.ceil(this.file.size / this.chunkSize); i++) {
this.chunks.push({
index: i,
start: i * this.chunkSize,
end: Math.min(this.file.size, (i + 1) * this.chunkSize),
uploaded: false,
});
}
}
// 上传分片
uploadChunk(chunk) {
const xhr = new XMLHttpRequest();
const formData = new FormData();
const blob = this.file.slice(chunk.start, chunk.end);
formData.append('file', blob, this.file.name);
formData.append('index', chunk.index);
xhr.open('POST', this.url, true);
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
// 更新进度(可根据需要自定义)
console.log(`Chunk ${chunk.index}: ${(event.loaded / event.total) * 100}%`);
}
};
xhr.onload = () => {
if (xhr.status === 200) {
chunk.uploaded = true;
this.progress = this.chunks.reduce((acc, curr) => acc + (curr.uploaded ? 1 : 0), 0) / this.chunks.length;
console.log(`Chunk ${chunk.index} uploaded successfully. Overall progress: ${this.progress * 100}%`);
this.uploadNextChunk(); // 上传下一个分片
} else {
console.error(`Chunk ${chunk.index} upload failed with status ${xhr.status}`);
// 错误处理,如重试等
}
};
xhr.onerror = () => {
console.error(`Chunk ${chunk.index} upload encountered an error`);
// 错误处理,如重试等
};
if (!this.paused) {
xhr.send(formData); // 开始上传分片
}
}
// 上传下一个未上传的分片
uploadNextChunk() {
const nextChunk = this.chunks.find((chunk) => !chunk.uploaded);
if (nextChunk) {
this.currentChunk = nextChunk.index;
this.uploadChunk(nextChunk); // 上传找到的分片
} else {
console.log('All chunks uploaded successfully'); // 所有分片上传完成
}
}
// 开始/恢复上传
start() {
this.paused = false;
if (this.currentChunk === 0) { // 如果是首次开始,则从头开始上传
this.uploadNextChunk(); // 上传第一个分片
} else { // 否则,继续上传当前分片(断点续传)
const currentChunk = this.chunks[this.currentChunk];
if (!currentChunk.uploaded) { // 如果当前分片未上传完,则继续上传该分片
this.uploadChunk(currentChunk); // 上传当前分片(断点续传)
} else { // 如果当前分片已上传完,则上传下一个分片(防止因网络等原因导致的上传状态不一致)
this.uploadNextChunk(); // 上传下一个分片(断点续传后的正常流程)
}
}
}
// 暂停上传
pause() {
this.paused = true; // 设置暂停标志,阻止后续上传操作(需配合XHR的abort方法使用,此处简化处理)
console.log('Upload paused'); // 输出暂停信息(可根据需要自定义)
}
}
使用方法:
const input = document.querySelector('input[type="file"]'); // 获取文件输入元素(可根据需要自定义)
input.addEventListener('change', (event) => {
const file = event.target.files[0]; // 获取选中的文件(可根据需要自定义)
const uploader = new ChunkedUploader(file, 'your-upload-endpoint'); // 创建ChunkedUploader实例,传入文件和上传接口URL(需替换为实际值)
uploader.start(); // 开始上传文件(可根据需要自定义调用时机和方式)
// uploader.pause(); // 暂停上传文件(可根据需要自定义调用时机和方式,如添加暂停按钮等)
});
注意:上述代码是一个简化的前端实现示例,主要展示了文件分片、上传进度跟踪和基本的暂停/恢复上传功能。在实际应用中,你还需要考虑更多的细节和异常情况,如网络错误重试、分片上传的并发控制、与后端服务器的通信协议等。此外,后端服务器也需要相应地支持断点续传功能,能够接收并处理分片上传的请求。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战