大文件上传是一个复杂的过程,尤其是在前端,我们需要考虑用户体验、网络状况、文件完整性等多个方面。
以下是一个使用HTML5的File API
和XMLHttpRequest
进行大文件分块上传的详解和示例代码。
一、前端分块上传流程
-
选择文件:使用
<input type="file">
元素让用户选择文件。 -
读取文件:使用
FileReader API
读取文件内容。 -
分块文件:根据设定的大小将文件切割成多个小块。
-
上传分块:使用
XMLHttpRequest
或fetch API
将每个分块上传到服务器。 -
合并文件:服务器接收到所有分块后,将其合并成完整的文件。
二、示例代码
以下是一个简单的示例代码,展示了如何使用JavaScript实现大文件的分块上传。
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>大文件分块上传</title>
</head>
<body> <input type="file" id="fileInput"> <button id="uploadButton">上传</button> <script> const chunkSize = 1024 * 1024; // 每块大小设置为1MB let fileInput = document.getElementById('fileInput'); let uploadButton = document.getElementById('uploadButton'); uploadButton.addEventListener('click', function () { let file = fileInput.files[0]; let chunks = Math.ceil(file.size / chunkSize); // 计算文件块数(文件总大小 / 每块大小)let currentChunk = 0; // 当前上传的块数 function uploadChunk() { if (currentChunk < chunks) { let start = currentChunk * chunkSize; // 计算当前要上传的分片的起始字节位置(已经上传的字节)let end = Math.min(file.size, start + chunkSize); // 计算当前要上传的分片的结束字节位置let chunk = file.slice(start, end); let formData = new FormData(); formData.append('chunk', chunk); formData.append('fileName', file.name); formData.append('totalChunks', chunks); formData.append('currentChunk', currentChunk); let xhr = new XMLHttpRequest(); xhr.open('POST', '/upload', true); // 替换为你的上传接口 xhr.upload.onprogress = function (e) { if (e.lengthComputable) { console.log((e.loaded / e.total * 100) + '%'); } }; xhr.onload = function () { if (xhr.status === 200) { currentChunk++; uploadChunk(); // 递归上传下一个块 } else { console.error('上传失败'); } }; xhr.send(formData); } else { console.log('上传完成'); } } uploadChunk(); // 开始上传第一个块 }); </script>
</body>
</html>
三、注意事项
-
文件完整性校验:上传完成后,服务器需要对合并后的文件进行完整性校验,确保文件没有损坏。
-
断点续传:在实际应用中,还需要考虑断点续传的功能,即当上传中断时,可以从上次中断的地方继续上传。
-
上传进度显示:在上传过程中,可以通过
XMLHttpRequest
的upload.onprogress
事件来显示上传进度。 -
错误处理:在上传过程中可能会遇到各种错误,如网络错误、服务器错误等,需要妥善处理这些错误,并给用户友好的提示。
-
安全性:在处理文件上传时,需要注意安全性问题,如防止恶意文件上传、防止跨站脚本攻击等。