You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:11:08