vue2项目中WebUploader怎样实现局域网大文件分块上传?
一个大三学生的文件管理系统血泪史前端篇各位看官我是浙江某高校网络工程专业的大三学生最近在搞一个史诗级项目——文件管理系统。为啥说是史诗级因为光是需求就快把我整秃噜皮了项目背景我们导师说“小张啊现在找工作得有作品你做个文件管理系统吧要支持10G大文件上传、加密传输、断点续传、文件夹层级保留还要兼容IE8”我“老师您这是要让我重写百度网盘吗”导师“不我要你超越百度网盘”我“…”技术选型经过一番挣扎我选择了前端Vue3 原生JS因为导师说不能用jQuery上传组件WebUploader兼容性好 H5现代浏览器用开发工具VSCode因为Sublime Text要钱数据库MySQL因为导师说这个最简单服务器本地Windows 7 IE9学校老机器的配置前端实现血泪版1. 兼容性处理首先得解决IE8兼容问题我写了这么个神器// 检测浏览器并给出友好提示functiondetectBrowser(){constuserAgentnavigator.userAgent;if(userAgent.indexOf(MSIE)-1||userAgent.indexOf(Trident)-1){constversionuserAgent.match(/(MSIE |rv:)(\d)/)[2];if(version9){alert(检测到您使用的是IEversion本系统需要IE9或其他现代浏览器);// 偷偷给IE用户显示个可爱图片document.body.innerHTML亲爱的IE用户 请使用Chrome/Firefox/Edge/Safari等现代浏览器;}}}detectBrowser();2. 文件上传组件封装classFileUploader{constructor(options){this.chunkSizeoptions.chunkSize||5*1024*1024;// 默认5MB分片this.fileInputdocument.getElementById(options.inputId);this.uploadBtndocument.getElementById(options.uploadBtnId);this.progressBardocument.getElementById(options.progressId);this.fileList[];this.initEvents();}initEvents(){this.fileInput.addEventListener(change,(e)this.handleFileSelect(e));this.uploadBtn.addEventListener(click,()this.startUpload());}handleFileSelect(e){constfilesArray.from(e.target.files);this.fileListfiles.map(file({file,chunks:[],uploadedChunks:0,totalChunks:Math.ceil(file.size/this.chunkSize),fileId:this.generateFileId()}));// 显示文件列表简化版console.log(已选择文件:,this.fileList.map(ff.file.name));}generateFileId(){returnxxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g,function(c){constrMath.random()*16|0;return(cx?r:(r0x3|0x8)).toString(16);});}// 加密函数简化版encryptData(data){// 实际项目中应该用AES等加密算法// 这里只是演示返回Base64编码returnbtoa(unescape(encodeURIComponent(data)));}// 分片上传asyncuploadChunk(fileObj,chunkIndex){constfilefileObj.file;conststartchunkIndex*this.chunkSize;constendMath.min(file.size,startthis.chunkSize);constchunkfile.slice(start,end);// 加密分片数据constencryptedChunkthis.encryptData(chunk);// 这里应该用XMLHttpRequest或Fetch API发送到后端// 但导师说后端要我自己写所以我只能...console.log(模拟上传分片${chunkIndex1}/${fileObj.totalChunks}:${file.name});// 模拟网络延迟awaitnewPromise(resolvesetTimeout(resolve,500));return{success:true,chunkIndex};}asyncstartUpload(){if(this.fileList.length0){alert(请先选择文件);return;}for(constfileObjofthis.fileList){try{for(leti0;ifileObj.totalChunks;i){constresultawaitthis.uploadChunk(fileObj,i);if(result.success){fileObj.uploadedChunks;this.updateProgress(fileObj);// 保存上传进度到localStorage断点续传this.saveProgressToStorage(fileObj);}}console.log(文件${fileObj.file.name}上传完成);}catch(error){console.error(上传文件${fileObj.file.name}时出错:,error);}}}updateProgress(fileObj){constpercent(fileObj.uploadedChunks/fileObj.totalChunks*100).toFixed(2);this.progressBar.style.widthpercent%;this.progressBar.textContentpercent%;}saveProgressToStorage(fileObj){constprogressData{fileId:fileObj.fileId,fileName:fileObj.file.name,uploadedChunks:fileObj.uploadedChunks,totalChunks:fileObj.totalChunks,fileSize:fileObj.file.size,lastModified:fileObj.file.lastModified};localStorage.setItem(uploadProgress_${fileObj.fileId},JSON.stringify(progressData));}// 从localStorage恢复上传进度staticrestoreProgress(){constprogressItems{};for(leti0;ilocalStorage.length;i){constkeylocalStorage.key(i);if(key.startsWith(uploadProgress_)){constdataJSON.parse(localStorage.getItem(key));progressItems[key]data;}}returnprogressItems;}}// 使用示例document.addEventListener(DOMContentLoaded,(){constuploadernewFileUploader({inputId:fileInput,uploadBtnId:uploadBtn,progressId:progressBar});// 恢复上传进度constprogressFileUploader.restoreProgress();console.log(恢复的上传进度:,progress);});3. Vue3组件封装export default { name: FileUploader, data() { return { files: [], chunkSize: 5 * 1024 * 1024, // 5MB uploadProgress: {} }; }, methods: { handleFileChange(e) { const files Array.from(e.target.files); // 处理文件夹上传WebKit browsers if (files.length 0 e.target.webkitEntries) { const entries Array.from(e.target.webkitEntries); this.processDirectoryEntries(entries); return; } this.files files.map(file ({ file, name: file.name, size: file.size, uploaded: false, uploadedSize: 0 })); }, processDirectoryEntries(entries) { // 实际项目中需要递归处理文件夹结构 // 这里简化处理只取文件 const files []; const processEntry (entry) { if (entry.isFile) { entry.file(file { files.push(file); if (files.length entries.length) { this.files files.map(file ({ file, name: file.name, size: file.size, uploaded: false, uploadedSize: 0 })); } }); } }; entries.forEach(processEntry); }, async startUpload() { if (this.files.length 0) { alert(请先选择文件或文件夹); return; } for (const fileObj of this.files) { try { await this.uploadFile(fileObj); fileObj.uploaded true; } catch (error) { console.error(上传文件 ${fileObj.name} 时出错:, error); } } }, async uploadFile(fileObj) { const file fileObj.file; const totalChunks Math.ceil(file.size / this.chunkSize); for (let i 0; i totalChunks; i) { const start i * this.chunkSize; const end Math.min(file.size, start this.chunkSize); const chunk file.slice(start, end); // 加密分片实际项目中应该用更安全的加密方式 const encryptedChunk this.simpleEncrypt(chunk); // 这里应该调用后端API上传分片 // 但导师说后端要我自己写所以我只能... console.log(上传分片 ${i 1}/${totalChunks}: ${file.name}); // 模拟网络延迟 await new Promise(resolve setTimeout(resolve, 300)); fileObj.uploadedSize end; this.updateProgress(); } }, simpleEncrypt(data) { // 超级简单的加密实际项目不能用 return data; // 这里应该返回加密后的数据 }, updateProgress() { const totalUploaded this.files.reduce((sum, file) sum file.uploadedSize, 0); const totalSize this.files.reduce((sum, file) sum file.size, 0); const percent Math.round((totalUploaded / totalSize) * 100); this.$refs.progressBar.style.width percent %; this.$refs.progressBar.nextElementSibling.textContent percent %; }, restoreUpload() { // 从localStorage恢复上传进度 const progressItems {}; for (let i 0; i localStorage.length; i) { const key localStorage.key(i); if (key.startsWith(uploadProgress_)) { const data JSON.parse(localStorage.getItem(key)); progressItems[key] data; } } console.log(恢复的上传进度:, progressItems); alert(上传进度已恢复控制台查看详情); }, formatFileSize(bytes) { if (bytes 0) return 0 Bytes; const k 1024; const sizes [Bytes, KB, MB, GB]; const i Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) sizes[i]; } }, mounted() { // 检测浏览器兼容性 this.detectBrowser(); }, methods: { detectBrowser() { const userAgent navigator.userAgent; if (userAgent.indexOf(MSIE) -1 || userAgent.indexOf(Trident) -1) { const version userAgent.match(/(MSIE |rv:)(\d)/)[2]; if (version 9) { alert(检测到您使用的是IE${version}本系统需要IE9或其他现代浏览器); document.body.innerHTML div styletext-align:center; padding:50px; h1亲爱的IE用户/h1 img srchttps://http.cat/418.jpg altIE已淘汰 p请使用Chrome/Firefox/Edge/Safari等现代浏览器/p /div ; } } } } }; .file-uploader { max-width: 800px; margin: 0 auto; padding: 20px; font-family: Arial, sans-serif; } .upload-area { margin: 20px 0; padding: 20px; border: 2px dashed #ccc; text-align: center; } .progress-container { margin: 20px 0; height: 30px; background: #f0f0f0; border-radius: 15px; position: relative; } .progress-bar { height: 100%; background: #4CAF50; border-radius: 15px; width: 0%; transition: width 0.3s; } .progress-text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #333; } .file-list { margin-top: 30px; } .file-list ul { list-style: none; padding: 0; } .file-list li { padding: 8px; border-bottom: 1px solid #eee; }项目趣事IE8兼容大战为了兼容IE8我尝试了各种polyfill最后发现还是直接显示请升级浏览器更实际文件夹上传WebUploader对文件夹上传支持不好我研究了半天发现原来要用webkitdirectory属性断点续传本来想用IndexedDB存储上传进度发现IE不支持最后改用localStorage虽然有大小限制加密传输研究了AES加密发现实现起来太复杂最后用了简单的Base64编码导师说这不算真正的加密求助与展望现在前端部分勉强能跑但后端完全没头绪。群里的小伙伴们也都在喊后端大佬救命在此我郑重声明不提供后端代码因为我也不会欢迎大佬加入QQ群374992201指导加群送1-99元红包老板说这是营销策略推荐工作成功者送20%项目提成虽然现在还没项目最后如果哪位师哥师姐愿意收我为徒教我后端开发我愿意每天给您请安帮您写前端代码毕业设计可以挂您名字未来第一年工资分您10%联系方式QQ群374992201群里找我求带的小张将组件复制到项目中示例中已经包含此目录引入组件配置接口地址接口地址分别对应文件初始化文件数据上传文件进度文件上传完毕文件删除文件夹初始化文件夹删除文件列表参考http://www.ncmem.com/doc/view.aspx?ide1f49f3e1d4742e19135e00bd41fa3de处理事件启动测试启动成功效果数据库效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。下载示例点击下载完整示例

相关新闻

vue3如何通过WebUploader在局域网实现大文件断点续传?

vue3如何通过WebUploader在局域网实现大文件断点续传?

前端程序员外包项目救星:原生JS大文件上传组件(Vue3实现) 兄弟,作为在杭州接外包的老前端程序员,太懂你现在的处境了——甲方要20G大文件上传,还要兼容IE9,预算卡得死死的,网上代码…

2026/7/4 22:23:41 阅读更多 →
jquery结合WebUploader在局域网实现大文件断点续传?

jquery结合WebUploader在局域网实现大文件断点续传?

第一章:毕业设计の终极挑战 "同学,你这毕业设计要做文件管理系统?还要支持10G大文件上传?"导师推了推眼镜,我仿佛看到他头顶飘着"这届学生真难带"的弹幕。 "是的老师!还要兼容I…

2026/7/3 16:42:50 阅读更多 →
OA系统开发中,KindEditor如何优化WORD截图复制流程?

OA系统开发中,KindEditor如何优化WORD截图复制流程?

(推了推黑框眼镜,手指在键盘上噼里啪啦敲击)各位老铁,咱北京程序员又来唠嗑了!最近接了个CMS官网的活儿,客户爸爸要求在KindEditor里整点花活——要能直接把Word/Excel/PPT/PDF里的内容连锅端到编辑器里&am…

2026/7/3 3:43:11 阅读更多 →

最新新闻

Qwen3.5全面升级:解耦架构与认知蒸馏驱动的企业级AI落地

Qwen3.5全面升级:解耦架构与认知蒸馏驱动的企业级AI落地

1. 项目概述:这不是一次常规迭代,而是一次底层能力的重新校准“Qwen3.5发布:通义千问系列的最新突破与全面升级”——这个标题里藏着一个容易被忽略但极其关键的信号:“全面升级”不是功能点的简单堆叠,而是模型架构、…

2026/7/4 22:22:31 阅读更多 →
LongDocURL:面向长文档理解的大模型多模态推理评测基准

LongDocURL:面向长文档理解的大模型多模态推理评测基准

1. 这不是又一个“刷分”评测集,而是一次对长文档理解能力的硬核压力测试你有没有试过让大模型读一份80页的财报PDF?不是扫一眼目录,而是真正理解其中某张附注表格和前后三页文字描述之间的逻辑关系;不是简单提取“净利润增长12%”…

2026/7/4 22:22:31 阅读更多 →
Umi-OCR终极指南:免费离线文字识别软件的完整配置与优化教程

Umi-OCR终极指南:免费离线文字识别软件的完整配置与优化教程

Umi-OCR终极指南:免费离线文字识别软件的完整配置与优化教程 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。内置多…

2026/7/4 22:12:22 阅读更多 →
postcss-write-svg:革命性CSS SVG编写工具,让图形开发效率提升10倍!

postcss-write-svg:革命性CSS SVG编写工具,让图形开发效率提升10倍!

postcss-write-svg:革命性CSS SVG编写工具,让图形开发效率提升10倍! 【免费下载链接】postcss-write-svg Write SVGs directly in CSS 项目地址: https://gitcode.com/gh_mirrors/po/postcss-write-svg 你是否厌倦了在CSS和SVG文件之间…

2026/7/4 22:12:21 阅读更多 →
3大架构优化策略:如何构建高可用AI网关服务

3大架构优化策略:如何构建高可用AI网关服务

3大架构优化策略:如何构建高可用AI网关服务 【免费下载链接】new-api A unified AI model hub for aggregation & distribution. It supports cross-converting various LLMs into OpenAI-compatible, Claude-compatible, or Gemini-compatible formats. A cent…

2026/7/4 22:12:21 阅读更多 →
Agent Skills技能发现机制:如何让AI助手智能匹配任务与技能

Agent Skills技能发现机制:如何让AI助手智能匹配任务与技能

Agent Skills技能发现机制:如何让AI助手智能匹配任务与技能 【免费下载链接】agentskills Specification and documentation for Agent Skills 项目地址: https://gitcode.com/GitHub_Trending/ag/agentskills Agent Skills是GitHub推荐项目精选(…

2026/7/4 22:10:20 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻