如何在JavaScript中暂停和恢复文件上传?附现有上传代码
实现文件上传的暂停与恢复功能
嘿,要在你现有的上传代码基础上实现暂停和恢复,核心是靠XMLHttpRequest的中断能力,加上文件切片(Blob.slice())来记录上传进度的断点。我来一步步帮你改造代码:
第一步:更新HTML结构,添加控制按钮
先给你的表单加上暂停和恢复按钮(初始时恢复按钮可以隐藏):
<form id="upload_form" enctype="multipart/form-data" method="post"> <input type="file" name="Files" id="file1" onchange="uploadFile()"><br> <progress id="progressBar" class='progressbar' value="0" max="100" style="width:300px;height:5px"></progress> <h3 id="status"></h3> <p id="loaded_n_total"></p> <!-- 新增控制按钮 --> <button type="button" id="pauseBtn" onclick="pauseUpload()">暂停上传</button> <button type="button" id="resumeBtn" onclick="resumeUpload()" style="display:none;">恢复上传</button> </form>
第二步:定义全局状态变量
在脚本开头定义几个全局变量,用来保存上传的关键状态:
let xhr; // 保存XMLHttpRequest实例 let startByte = 0; // 记录已上传的字节数 let currentFile; // 保存当前上传的文件对象 const statusElement = document.getElementById('status'); const progressBar = document.getElementById('progressBar'); const loadedText = document.getElementById('loaded_n_total'); const pauseBtn = document.getElementById('pauseBtn'); const resumeBtn = document.getElementById('resumeBtn');
第三步:改造上传逻辑,支持断点续传
修改uploadFile函数,让它支持从指定字节位置开始上传:
function uploadFile() { currentFile = document.getElementById('file1').files[0]; if (!currentFile) return; // 重置状态(如果是第一次上传) startByte = 0; statusElement.textContent = '准备上传...'; progressBar.value = 0; // 调用实际的上传函数 sendUploadRequest(); } function sendUploadRequest() { xhr = new XMLHttpRequest(); const uploadUrl = '/your-upload-endpoint'; // 替换成你的后端上传接口 xhr.open('POST', uploadUrl, true); // 设置Range头,告诉后端从哪个字节开始上传 xhr.setRequestHeader('Range', `bytes=${startByte}-${currentFile.size}`); // 监听进度事件 xhr.upload.addEventListener('progress', handleProgress); // 监听上传完成/失败事件 xhr.addEventListener('load', handleUploadComplete); xhr.addEventListener('error', handleUploadError); xhr.addEventListener('abort', handleUploadAbort); // 构造FormData,只上传文件的切片部分 const formData = new FormData(); // 从startByte位置开始切片文件 const fileSlice = currentFile.slice(startByte); formData.append('Files', fileSlice, currentFile.name); // 发送请求 xhr.send(formData); }
第四步:实现暂停和恢复函数
添加暂停和恢复的逻辑:
function pauseUpload() { if (xhr && xhr.readyState !== 4) { xhr.abort(); statusElement.textContent = '上传已暂停'; pauseBtn.style.display = 'none'; resumeBtn.style.display = 'inline-block'; } } function resumeUpload() { statusElement.textContent = '恢复上传...'; pauseBtn.style.display = 'inline-block'; resumeBtn.style.display = 'none'; // 从上次中断的位置继续上传 sendUploadRequest(); }
第五步:完善进度和状态处理函数
更新进度监听和状态回调:
function handleProgress(e) { if (e.lengthComputable) { // 计算总上传进度:(已上传字节 + 本次上传的字节) / 文件总大小 * 100 const totalUploaded = startByte + e.loaded; const percentComplete = (totalUploaded / currentFile.size) * 100; progressBar.value = percentComplete; loadedText.textContent = `${totalUploaded} / ${currentFile.size} 字节`; statusElement.textContent = `上传中:${Math.round(percentComplete)}%`; // 更新startByte,记录当前已上传的总字节数 startByte = totalUploaded; } } function handleUploadComplete() { if (xhr.status === 200 || xhr.status === 206) { // 206是部分内容成功的状态码 statusElement.textContent = '上传完成!'; pauseBtn.style.display = 'none'; resumeBtn.style.display = 'none'; } else { statusElement.textContent = `上传失败:${xhr.statusText}`; } } function handleUploadError() { statusElement.textContent = '上传出错,请检查网络'; } function handleUploadAbort() { statusElement.textContent = '上传已取消'; }
重要注意事项
- 后端必须支持断点续传:你的后端接口需要能解析
Range请求头,把接收到的文件切片追加到已上传的文件中,而不是覆盖。如果后端不支持,前端的暂停恢复逻辑是无效的。 - 兼容性:
Blob.slice()在不同浏览器的早期版本有不同的写法(比如mozSlice、webkitSlice),如果需要兼容旧浏览器,可以加个兼容处理:const slice = currentFile.slice || currentFile.mozSlice || currentFile.webkitSlice; const fileSlice = slice.call(currentFile, startByte);
内容的提问来源于stack exchange,提问作者Karthik Ravichandran
相关产品推荐
相关产品推荐

