本文主要是介绍文件上传之大文件分块上传进度控制处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在分块上传内容结束以后的事件监听,我们会实现 unlinkSync 删除临时文件操作,那么试想一下,在这个事件监听中,我们是否可以通过totalChunks以及currentChunk获取当前上传的进度情况呢?
后端
upload上传接口:
app.post('/upload',upload.single('file'),(req,res) => {const file = req.file; const filename = req.body.filename;const totalChunks = parseInt(req.body.totalChunks); // 获取总块数const currentChunk = parseInt(req.body.currentChunk); // 获取当前块数const chunkPath = path.join("uploads/",`${filename}-chunk-${currentChunk}`); const chunkStream = fs.createReadStream(file.path);const writeStream = fs.createWriteStream(chunkPath);chunkStream.pipe(writeStream);// 对分块上传内容结束以后的事件监听chunkStream.on("end", () => {fs.unlinkSync(file.path); //读取文件块的流结束后,删除临时文件// 打印 progress 我们就可以获取到文件进度情况const progress = ((currentChunk + 1) / totalChunks) * 100; // 计算上传进度情况res.json({ progress }); // 服务器端向客户端进行返回操作});
});
前端
html:
<input type="file" id="fileInput">
<progress value="0" max="100" id="progress"></progress> //设置一个进度条
<button onclick="upload()">上传文件</button>
script:
async function upload() {const fileInput = document.getElementById('fileInput'); //获取input框const file = fileInput.files[0]; // 对input的文件进行获取const chunkSize = 1*1024*1024; //初始化分块的尺寸 每块分块文件大小为1MB(1兆)const totalChunks = Math.ceil(file.size / chunkSize); //通过文件尺寸计算出所有的块数let currentChunk = 0; //设置块的初始值// 通过while循环处理while (currentChunk < totalChunks){const start = currentChunk * chunkSize; // 计算当前块的起始位置const end = Math.min(start + chunkSize, file.size); // 计算当前块的结束 Math.min:返回一组数值中的最小值const chunk = file.slice(start, end); // 切割文件获取当前块const formData = new FormData();formData.append('file', chunk); // 添加当前块到 FormData 对象formData.append('filename', file.name); // 添加文件名到 FormData 对象formData.append('totalChunks', totalChunks); // 添加总块数到 FormData 对象formData.append('currentChunk', currentChunk); // 添加当前块数到 FormData 对象try{// 获取返回的内容(进度)const res = await axios.post('http://localhost:3000/upload',formData,{headers:{'Content-Type':'multipart/form-data',},}); //发送当前块的上传请求const { progress } = res.data; // 获取当前块的上传进度document.getElementById('progress').value = progress; // 更新进度}catch(error){console.error(error);return;}currentChunk++; //增加当前块数,继续下一块的上传(实现循环操作)}// 当所有分块文件发送完毕,发起合并请求操作try{const postData = { filename:file.name,totalChunks:totalChunks }; //构造合并请求的数据await http.post('http://localhost:3000/merge', postData,{headers: {'Content-Type': 'application/json'}}); //发送合并请求}catch(error){console.error(error);}
}
再次发送文件,进度条已经正常显示:
这篇关于文件上传之大文件分块上传进度控制处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!