如何通过jQuery二次请求实现带XHR进度条的文件上传?
嘿,我明白你已经搞定了带XHR进度条的单请求文件上传,现在想要通过第二次jQuery请求实现文件上传相关的需求——不管是分批次传大文件、先拿上传权限再执行上传,还是上传完成后触发二次校验,我给你几个贴合你现有代码结构的实用方案:
方案1:分批次上传大文件(两次请求拆分文件)
如果是要把大文件拆成两部分分两次上传,你可以复用现有的XHR进度逻辑,只需要给Upload类加一个分片处理的方法,然后依次发起两次AJAX请求:
// 扩展你的Upload类 Upload.prototype.uploadInChunks = function(file) { const chunkSize = 1024 * 1024 * 5; // 5MB分片 const totalChunks = Math.ceil(file.size / chunkSize); let currentChunk = 0; // 定义分片上传逻辑,自动触发第二次请求 const uploadChunk = () => { const start = currentChunk * chunkSize; const end = Math.min(start + chunkSize, file.size); const chunk = file.slice(start, end); const formData = new FormData(); formData.append('fileChunk', chunk); formData.append('chunkIndex', currentChunk); formData.append('totalChunks', totalChunks); formData.append('fileName', file.name); $.ajax({ url: "../Services/upload.ashx", type: "POST", data: formData, cache: false, contentType: false, processData: false, timeout: 60000, xhr: () => { const myXhr = $.ajaxSettings.xhr(); if (myXhr.upload) { // 复用你已有的进度处理方法,可额外传递分片信息 myXhr.upload.addEventListener('progress', (e) => { this.progressHandling(e, currentChunk, totalChunks); }, false); } return myXhr; }, success: () => { currentChunk++; if (currentChunk < totalChunks) { // 触发第二次(或后续)上传请求 uploadChunk(); } else { alert('文件上传完成'); } }, error: (err) => { console.error('分片上传失败', err); } }); }; // 启动第一次上传 uploadChunk(); }; // 扩展进度处理方法,支持分片进度展示 Upload.prototype.progressHandling = function(event, chunkIndex = 0, totalChunks = 1) { if (event.lengthComputable) { // 单分片进度 const chunkPercent = Math.round((event.loaded / event.total) * 100); // 整体进度 const totalPercent = Math.round(((chunkIndex * 100) + chunkPercent) / totalChunks); console.log(`整体进度:${totalPercent}%,当前分片进度:${chunkPercent}%`); // 这里替换成你的DOM更新逻辑 } };
方案2:先发起预请求拿上传凭证,再执行实际上传
如果需要先通过第一次请求获取上传权限、token或其他参数,再用第二次请求完成文件上传:
Upload.prototype.uploadWithPreRequest = function(file) { // 第一次请求:获取上传凭证 $.ajax({ url: "../Services/getUploadToken.ashx", type: "GET", success: (tokenData) => { // 第二次请求:带凭证上传文件 const formData = new FormData(); formData.append('file', file); formData.append('uploadToken', tokenData.token); $.ajax({ url: "../Services/upload.ashx", type: "POST", data: formData, cache: false, contentType: false, processData: false, timeout: 60000, xhr: () => { const myXhr = $.ajaxSettings.xhr(); if (myXhr.upload) { myXhr.upload.addEventListener('progress', this.progressHandling, false); } return myXhr; }, success: () => { alert('文件上传成功'); }, error: (err) => { console.error('上传失败', err); } }); }, error: (err) => { console.error('获取上传凭证失败', err); } }); };
方案3:上传完成后触发二次校验/通知请求
如果是第一次请求完成文件上传后,需要发起第二次请求通知后端处理文件或校验上传结果:
// 基于你现有的上传代码改造 $.ajax({ url: "../Services/upload.ashx", type: "POST", data: formData, cache: false, contentType: false, processData: false, timeout: 60000, xhr: function () { var myXhr = $.ajaxSettings.xhr(); if (myXhr.upload) { myXhr.upload.addEventListener('progress', that.progressHandling, false); } return myXhr; }, success: (uploadResult) => { // 第一次上传成功后,发起第二次校验请求 $.ajax({ url: "../Services/verifyUpload.ashx", type: "POST", data: { fileId: uploadResult.fileId, fileName: uploadResult.fileName }, success: (verifyResult) => { if (verifyResult.success) { alert('文件上传并校验完成'); } else { alert('文件校验失败,请重新上传'); } }, error: (err) => { console.error('校验请求失败', err); } }); }, error: (err) => { console.error('上传失败', err); } });
注意事项
- 不管哪种方案,都要确保后端
upload.ashx(或对应接口)支持对应的逻辑:比如分片上传需要后端合并分片,预请求需要后端生成凭证,二次校验需要后端验证文件完整性。 - 你可以直接复用现有
progressHandling方法,只需要根据场景调整进度计算逻辑即可。
内容的提问来源于stack exchange,提问作者Radek
相关产品推荐
相关产品推荐

