跨平台网页应用如何用vue实现文件夹上传?

前端老炮的20G文件夹上传大冒险(附部分代码)

各位前端同仁们,我是老张,一个在辽宁苦哈哈写代码的"前端民工"。最近接了个活,客户要求用原生JS实现20G文件夹上传下载,还要支持IE9!这简直是要了我这把老骨头的命啊!不过为了那100块预算(划掉),为了技术理想,我决定拼了!

项目背景(哭诉版)

客户要求:

  • 20G大文件上传(这是要上传整个硬盘吗?)
  • 文件夹上传保留层级结构(1000个分类的文件,这是要搞文件管理系统吗?)
  • 支持SM4/AES加密(这是要搞国家机密吗?)
  • 断点续传(用户重启电脑都不能丢进度,这是要我做操作系统吗?)
  • 兼容IE9(现在还有人用IE9?哦,是Windows 7用户,好吧,我理解)
  • 预算100元以内(这连买杯咖啡都不够啊!)
  • 7*24小时技术支持(这是要把我当24小时客服吗?)
  • 3年免费维护(这是要签终身合同吗?)

技术选型(妥协版)

经过深思熟虑,我决定:

  • 前端:Vue3 + 原生JS(因为客户说不能用WebUploader)
  • 后端:SpringBoot(但我不写后端代码,哈哈)
  • 加密:crypto-js(因为IE9不支持Web Crypto API)
  • 文件分片:自己实现(因为找不到现成的IE9兼容方案)

部分前端代码(救命版)

以下是文件夹上传的核心代码,其他功能你们自己实现吧(逃):

20G文件夹上传神器(IE9兼容版) body { font-family: 'Microsoft YaHei', sans-serif; margin: 20px; } .progress-container { width: 100%; background: #f0f0f0; margin: 10px 0; } .progress-bar { height: 20px; background: #4CAF50; width: 0%; text-align: center; line-height: 20px; color: white; } .file-list { margin-top: 20px; border: 1px solid #ddd; padding: 10px; max-height: 300px; overflow-y: auto; } 20G文件夹上传神器(IE9兼容版) 选择文件夹 开始上传 暂停上传 0% 文件列表: // 全局变量(IE9兼容的"类"实现) var FileUploader = { files: [], chunkSize: 5 * 1024 * 1024, // 5MB分片 uploadId: null, paused: false, // 初始化(IE9兼容版) init: function() { document.getElementById('fileInput').addEventListener('change', this.handleFileSelect.bind(this)); // 模拟断点续传的本地存储(IE9用userData或cookie,这里简化用localStorage) if (!localStorage.getItem('uploadProgress')) { localStorage.setItem('uploadProgress', JSON.stringify({})); } }, // 处理文件夹选择(IE9兼容版) handleFileSelect: function(e) { this.files = []; var fileList = e.target.files; // 递归构建文件树(IE9没有File.webkitRelativePath,需要特殊处理) for (var i = 0; i < fileList.length; i++) { var file = fileList[i]; // 这里简化处理,实际需要解析webkitRelativePath或手动构建路径 // 兼容IE9的替代方案:让用户先压缩成zip...(开玩笑的) this.files.push({ file: file, path: file.name, // 实际应该用webkitRelativePath uploaded: 0, total: file.size, chunks: Math.ceil(file.size / this.chunkSize), uploadedChunks: 0 }); } this.renderFileList(); }, // 渲染文件列表(IE9兼容版) renderFileList: function() { var list = document.getElementById('fileList'); list.innerHTML = ''; for (var i = 0; i < this.files.length; i++) { var file = this.files[i]; var item = document.createElement('li'); item.innerHTML = file.path + ' (' + this.formatFileSize(file.uploaded) + '/' + this.formatFileSize(file.total) + ')'; list.appendChild(item); } }, // 格式化文件大小(IE9兼容版) formatFileSize: function(bytes) { if (bytes === 0) return '0 Bytes'; var k = 1024; var sizes = ['Bytes', 'KB', 'MB', 'GB']; var i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }, // 开始上传(IE9兼容版) startUpload: function() { if (this.files.length === 0) { alert('请先选择文件夹'); return; } this.paused = false; this.uploadId = new Date().getTime(); // 简单生成上传ID // 加载之前的上传进度 var progressData = JSON.parse(localStorage.getItem('uploadProgress')); for (var i = 0; i < this.files.length; i++) { var file = this.files[i]; var fileId = file.path; // 实际应该用更唯一的ID // 如果有之前的上传记录,从断点继续 if (progressData[fileId] && progressData[fileId].uploadId === this.uploadId) { file.uploaded = progressData[fileId].uploaded; file.uploadedChunks = progressData[fileId].uploadedChunks; } else { progressData[fileId] = { uploadId: this.uploadId, uploaded: 0, uploadedChunks: 0 }; } } localStorage.setItem('uploadProgress', JSON.stringify(progressData)); this.uploadNextChunk(); }, // 上传下一个分片(IE9兼容版) uploadNextChunk: function() { if (this.paused) return; var fileToUpload = null; var fileIndex = -1; // 查找下一个需要上传的分片 for (var i = 0; i < this.files.length; i++) { var file = this.files[i]; if (file.uploadedChunks < file.chunks) { fileToUpload = file; fileIndex = i; break; } } if (!fileToUpload) { alert('上传完成!'); return; } var chunkIndex = fileToUpload.uploadedChunks; var start = chunkIndex * this.chunkSize; var end = Math.min(start + this.chunkSize, fileToUpload.total); var chunk = fileToUpload.file.slice(start, end); // 加密分片(IE9兼容版) var encryptedChunk = this.encryptData(chunk, 'secret-key-123'); // 实际应该用用户提供的密钥 // 模拟上传(实际应该用XMLHttpRequest或ActiveXObject for IE9) console.log('上传分片:', fileToUpload.path, '分片', chunkIndex, '/', fileToUpload.chunks); // 更新进度(IE9兼容版) fileToUpload.uploadedChunks++; fileToUpload.uploaded = end; // 保存上传进度 var progressData = JSON.parse(localStorage.getItem('uploadProgress')); var fileId = fileToUpload.path; progressData[fileId] = { uploadId: this.uploadId, uploaded: fileToUpload.uploaded, uploadedChunks: fileToUpload.uploadedChunks }; localStorage.setItem('uploadProgress', JSON.stringify(progressData)); // 更新UI this.renderFileList(); this.updateProgressBar(); // 继续上传下一个分片(使用setTimeout模拟异步) var self = this; setTimeout(function() { self.uploadNextChunk(); }, 100); // 模拟网络延迟 }, // 加密数据(IE9兼容版) encryptData: function(data, key) { // 实际应该用SM4或AES,这里简化用CryptoJS的AES // IE9需要额外处理ArrayBuffer到WordArray的转换 if (data instanceof Blob) { return new Promise(function(resolve) { var reader = new FileReader(); reader.onload = function(e) { var words = CryptoJS.enc.Latin1.parse(e.target.result); var encrypted = CryptoJS.AES.encrypt(words, key).toString(); resolve(encrypted); }; reader.readAsBinaryString(data); }); } // 简化处理,实际需要更复杂的实现 return CryptoJS.AES.encrypt(data, key).toString(); }, // 暂停上传(IE9兼容版) pauseUpload: function() { this.paused = true; alert('上传已暂停'); }, // 更新进度条(IE9兼容版) updateProgressBar: function() { var totalUploaded = this.files.reduce(function(sum, file) { return sum + file.uploaded; }, 0); var totalSize = this.files.reduce(function(sum, file) { return sum + file.total; }, 0); var percent = Math.round((totalUploaded / totalSize) * 100); document.getElementById('progressBar').style.width = percent + '%'; document.getElementById('progressBar').innerHTML = percent + '%'; } }; // 初始化(页面加载时执行) window.onload = function() { FileUploader.init(); // 兼容IE9的console.log(IE9没有console对象时) if (!window.console) { window.console = { log: function() {} }; } }; // 暴露全局方法(IE9兼容) window.startUpload = function() { FileUploader.startUpload(); }; window.pauseUpload = function() { FileUploader.pauseUpload(); };

开发心得(吐槽版)

  1. IE9兼容性:这简直是一场噩梦!没有File API,没有Promise,没有const/let,没有箭头函数…我感觉自己在用石器时代的工具开发火箭。

  2. 文件夹上传:现代浏览器有webkitRelativePath,但IE9没有。解决方案?要么让用户先压缩成zip,要么…算了,还是压缩吧(客户肯定不同意)。

  3. 断点续传:localStorage在IE9中只有5MB限制,存储大量上传进度?呵呵,祝你好运。

  4. 加密传输:IE9不支持Web Crypto API,只能用crypto-js这种老库,性能感人。

  5. 20G文件:分片上传是必须的,但IE9的内存管理…算了,别让浏览器崩溃就是胜利。

加入我们的接单群(广告版)

各位同仁,如果你也在为这些奇葩需求头疼,或者想找项目合作,欢迎加入我们的QQ群:374992201

群内福利:

  • 1~99元超级大红包(每天都有)
  • 接单合作机会
  • 技术交流分享
  • 推荐项目拿20%提成
  • 超级会员50%提成(躺着赚钱)

免责声明(求生版)

以上代码仅供娱乐参考,实际项目中请:

  1. 使用成熟的库(如WebUploader、Plupload等)
  2. 考虑使用Flash作为IE9的备选方案
  3. 对于20G文件,建议使用专业的大文件传输方案
  4. 加密传输请使用标准协议(如TLS)而非前端加密
  5. 断点续传最好由后端实现

最后,祝大家项目顺利,少遇奇葩需求!如果真有客户找上门,记得推荐给我啊(手动狗头)!

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表
参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

下载示例

点击下载完整示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1173499.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【技术内幕】为什么你写的 Python 翻译脚本总是不好用?揭秘工业级 AI 图片翻译的“四步流水线”

Python 系统架构 计算机视觉 OCR AIGC 跨境电商摘要在跨境电商的自动化浪潮中&#xff0c;图片翻译&#xff08;Image Translation&#xff09; 是需求最旺盛的场景。许多开发者试图通过拼接开源库&#xff08;如 pytesseract, googletrans, Pillow&#xff09;来实现这一功能&…

ALLEGRO怎么给铜皮倒角

如果你想其中一个倒角

军工企业网页项目怎么实现文件夹上传功能?

大文件传输系统技术方案设计与实现&#xff08;第一人称专业报告&#xff09; 一、项目背景与需求分析 作为广西某软件公司前端工程师&#xff0c;近期负责一个关键项目的大文件传输模块开发。该项目需求具有以下特点&#xff1a; 支持20GB级大文件传输&#xff08;上传/下载…

【Python自动化】手机壳/T恤卖家的福音:如何用“主从克隆”技术瞬间搞定 100 个 SKU 变体的图片翻译?

Python 多变体运营 SKU管理 图像合成 跨境电商摘要在跨境电商&#xff08;如 Amazon Merch, Etsy, Casetify 模式&#xff09;中&#xff0c;多变体&#xff08;Multi-Variant&#xff09; 产品是管理的噩梦。一款手机壳可能有 50 种花色&#xff0c;一款 T 恤可能有 20 种底色…

2026年服务好的专卖店施工公司电话大盘点,靠谱企业全揭秘 - 工业品牌热点

在消费升级与品牌体验经济的浪潮下,专卖店作为品牌与消费者直接对话的线下橱窗,其空间设计与施工品质直接决定了品牌形象的传递效率与用户转化效果。面对市场上良莠不齐的专卖店施工与设计服务,如何找到既懂品牌调性…

《P1850 [NOIP 2016 提高组] 换教室》

题目背景NOIP2016 提高组 D1T3题目描述对于刚上大学的牛牛来说&#xff0c;他面临的第一个问题是如何根据实际情况申请合适的课程。在可以选择的课程中&#xff0c;有 2n 节课程安排在 n 个时间段上。在第 i&#xff08;1≤i≤n&#xff09;个时间段上&#xff0c;两节内容相同…

【Python视觉实战】文字压住产品纹理怎么办?揭秘 AI 如何在“网眼/毛绒”材质上实现无痕去字

Python AIGC 图像修复 Inpainting 计算机视觉 跨境电商摘要在跨境电商的素材处理中&#xff0c;最令美工崩溃的场景莫过于**“文字与产品纹理重叠”。当中文卖点直接印在运动鞋的透气网面、羽绒服的复杂的缝线、或是实木家具的纹理上时&#xff0c;传统的仿制图章工具几乎无法还…

汽车制造行业CMS如何集成UEDITOR实现WORD公式自动上传?

一个C#程序员的UEditorWord导入奇幻漂流&#xff1a;从.NET到Vue的魔幻联动 第一章&#xff1a;需求降临——老板的"简单"需求 "小王啊&#xff0c;咱们后台编辑器得加个Word导入功能&#xff0c;要保留格式和图片啊&#xff01;“老板轻描淡写的一句话&#…

【图像加密解密】基于matlab Arnold置乱变换图像加密解密【含Matlab源码 14960期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…

【Python视觉】1688长图怎么上亚马逊?揭秘 AI 如何智能“切割”并重构超长详情页

Python 计算机视觉 详情页优化 智能切图 跨境电商摘要在将国内 1688 或淘宝的爆款商品引入跨境平台&#xff08;Amazon, Shopee&#xff09;时&#xff0c;卖家面临的最大格式障碍是 “详情页长图&#xff08;Long Scroll Image&#xff09;”。简单的固定像素切割&#xff08;…

【图像加密解密】Arnold置乱变换图像加密解密【含Matlab源码 14960期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

互联网站群程序如何通过百度UE优化微信公众号内容导入?

一个Java程序员的UEditorWord导入血泪史&#xff1a;从抓狂到真香 第一章&#xff1a;需求降临——老板的"简单"要求 "小张啊&#xff0c;咱们后台编辑器得加个功能&#xff0c;用户要能直接导入Word文档&#xff0c;格式和图片都不能丢啊&#xff01;"老…

【图像加密解密】DNA编码混沌系统图像加密解密(数据丢失攻击测试、直方图分析、熵值计算、PSNR 峰值信噪比、像素相关性分析)【含Matlab源码 14961期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

芯片制造企业如何利用百度富文本编辑器实现PDF跨平台编辑?

今天早上刚到工位&#xff0c;就收到一位网友的微信私聊——原来是某初中学校外包项目的对接人&#xff0c;想咨询Word文档一键导入功能的实现方案。其实我的微信号早在技术社区公开过&#xff0c;但仍有不少开发者表示"大海捞针"&#xff0c;这找技术资源的难度堪比…

【图像加密解密】分数阶傅立叶变换和曲线锯变换图像加密解密【含Matlab源码 14962期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab武动乾坤博客之家&#x1f49e;…

‌AI自动生成“测试数据血缘图”:重构软件测试中的Bug源头追踪范式

一、AI驱动的测试数据血缘图&#xff0c;正在将Bug定位时间从“天级”压缩至“分钟级”‌传统测试中&#xff0c;定位一个线上缺陷常需人工翻查日志、比对代码、追溯数据库变更&#xff0c;耗时数小时甚至数日。而基于AI的‌自动化测试数据血缘图‌&#xff0c;通过动态构建“数…

西门子S7-200 SMART PLC与MCGS7.7触摸屏控制台达伺服电机位置模式的接线与参...

西门子S7-200SMART型PLC和MCGS7.7触摸屏控制台达伺服电机位置模式,带接线说明参数说明和运行效果视频最近在项目中用到了西门子S7-200 SMART PLC搭配MCGS7.7触摸屏控制台达ASD-A2系列伺服电机&#xff0c;折腾两天终于跑通了位置模式控制。分享下具体实现过程&#xff0c;包含硬…

Node.js用axios并发请求提速

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Node.js Axios并发请求优化&#xff1a;从性能瓶颈到智能提速策略目录Node.js Axios并发请求优化&#xff1a;从性能瓶颈到智能提…

【HarmonyOS NEXT】解决:软键盘弹起导致页面整体上移、标题栏丢失的问题

一、背景 在开发鸿蒙 APP 登录页时&#xff0c;会遇到这样的体验问题&#xff0c;当用户点击输入框弹出软键盘时&#xff0c;整个页面会被默认的上推模式带起&#xff0c;导致顶部的标题栏被推出可视区域&#xff0c;严重影响用户体验。 备注&#xff1a;以下解决方法为&…

我用AI分析测试日志,自动聚类相似失败模式

在当今快速迭代的软件开发环境中&#xff0c;测试日志是质量保障&#xff08;QA&#xff09;的核心资产。它们记录了测试用例的执行结果、错误信息和系统行为&#xff0c;但面对成千上万的日志条目&#xff0c;手动分析变得低效且易出错。尤其当多个失败案例&#xff08;failur…