vue大文件上传的切片上传与分块策略对比分析

前端老兵的20G文件夹上传血泪史(附部分代码)

各位前端同仁们好,我是老王,一个在福建靠写代码混口饭吃的"前端民工"。最近接了个奇葩项目,客户要求用原生JS实现20G文件夹上传下载,还要兼容IE9!这简直是要了我这把老骨头的命啊!

项目奇葩需求大赏

  1. 20G文件传输:客户说他们每天要传"大量资料",我第一反应是"您这是要传整个互联网吗?"
  2. 文件夹层级保留:要求上传1000个分类的文件,还要保持结构,这比整理我家衣柜还难
  3. 加密传输存储:SM4+AES双加密,我怀疑客户在搞什么国家机密
  4. 断点续传:关闭浏览器、重启电脑都不能丢进度,这比记住女朋友生日还难
  5. 非打包下载:几万个文件单独下载,这是要测试我家网速吗?
  6. 100元预算:是的,你没看错,100块!连我喝咖啡的钱都不够
  7. 免费3年维护:客户说"年轻人要讲武德",我差点把键盘吃了

文件夹上传技术实现(部分代码)

经过我日夜奋战(其实是熬夜掉头发),终于搞定了文件夹上传的核心功能。以下是部分原生JS实现代码:

20G文件夹上传神器(IE9兼容版) .upload-container { padding: 20px; font-family: 'Microsoft YaHei', sans-serif; } .progress-container { margin-top: 20px; border: 1px solid #ddd; padding: 10px; } .file-tree { margin-top: 20px; border: 1px solid #eee; padding: 10px; max-height: 300px; overflow-y: auto; } 文件夹上传系统(IE9兼容版) 选择文件夹 上传进度: 0% 文件夹结构: // 全局变量存储文件信息(IE9兼容的存储方案) const fileStorage = { files: [], currentChunk: 0, totalChunks: 0, uploadId: null, // 模拟本地存储(IE9没有localStorage的完整实现) save: function(key, value) { try { if (window.localStorage) { localStorage.setItem(key, JSON.stringify(value)); } else { // IE9兼容方案 - 使用userData或cookie(这里简化处理) document.cookie = key + '=' + encodeURIComponent(JSON.stringify(value)) + '; path=/'; } } catch (e) { console.error('存储失败:', e); } }, load: function(key) { try { if (window.localStorage) { const value = localStorage.getItem(key); return value ? JSON.parse(value) : null; } else { // IE9兼容方案 const name = key + '='; const ca = document.cookie.split(';'); for(let i=0; i<ca.length; i++) { let c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1); if (c.indexOf(name) == 0) return JSON.parse(decodeURIComponent(c.substring(name.length, c.length))); } return null; } } catch (e) { console.error('读取失败:', e); return null; } } }; // 处理文件夹选择 document.getElementById('folderInput').addEventListener('change', function(e) { const files = e.target.files; if (!files || files.length === 0) return; // 构建文件树结构 const fileTree = buildFileTree(files); document.getElementById('fileTree').innerHTML = renderFileTree(fileTree, ''); // 存储文件信息用于后续上传 fileStorage.files = Array.from(files).map(file => ({ name: file.webkitRelativePath || file.name, size: file.size, type: file.type, lastModified: file.lastModified, chunks: Math.ceil(file.size / (1024 * 1024)) // 每块1MB })); // 初始化上传状态 fileStorage.totalChunks = fileStorage.files.reduce((sum, file) => sum + file.chunks, 0); fileStorage.currentChunk = 0; fileStorage.uploadId = Date.now() + '-' + Math.random().toString(36).substr(2); // 保存上传状态 fileStorage.save('uploadState_' + fileStorage.uploadId, { files: fileStorage.files, currentChunk: 0, totalChunks: fileStorage.totalChunks }); }); // 构建文件树(简化版) function buildFileTree(files) { const tree = {}; Array.from(files).forEach(file => { const pathParts = (file.webkitRelativePath || file.name).split('/'); let currentLevel = tree; pathParts.forEach((part, index) => { if (index === pathParts.length - 1) { // 文件节点 currentLevel[part] = { isFile: true, size: file.size, type: file.type }; } else { // 目录节点 if (!currentLevel[part]) { currentLevel[part] = {}; } currentLevel = currentLevel[part]; } } }); }); return tree; } // 渲染文件树(简化版) function renderFileTree(tree, path) { let html = '<ul>'; for (const key in tree) { const node = tree[key]; const currentPath = path ? path + '/' + key : key; if (node.isFile) { html += `<li>${key} (${formatFileSize(node.size)})</li>`; } else { html += `<li><strong>${key}/</strong>`; html += renderFileTree(node, currentPath); html += '</li>'; } } html += '</ul>'; return html; } // 格式化文件大小 function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // 模拟上传过程(实际项目中需要替换为真实的AJAX请求) function startUpload() { if (fileStorage.files.length === 0) return; // 这里应该实现分块上传逻辑 // 由于篇幅限制,只展示进度更新部分 const interval = setInterval(() => { fileStorage.currentChunk++; const progress = Math.min(100, Math.round((fileStorage.currentChunk / fileStorage.totalChunks) * 100)); document.getElementById('progressText').textContent = progress + '%'; document.getElementById('uploadProgress').value = progress; // 保存进度 fileStorage.save('uploadProgress_' + fileStorage.uploadId, { progress: progress, currentChunk: fileStorage.currentChunk, totalChunks: fileStorage.totalChunks }); if (progress >= 100) { clearInterval(interval); alert('上传完成!(模拟)'); } }, 500); // 模拟上传速度 } // 页面加载时检查是否有未完成的上传 window.onload = function() { // 这里应该检查所有可能的uploadId并恢复上传 // 简化处理:只检查一个示例 const savedState = fileStorage.load('uploadProgress_example123'); if (savedState && savedState.progress > 0 && savedState.progress < 100) { if (confirm('检测到未完成的上传,是否继续?')) { document.getElementById('progressText').textContent = savedState.progress + '%'; document.getElementById('uploadProgress').value = savedState.progress; // 实际项目中需要恢复上传状态 } } };

开发过程中的血泪教训

  1. IE9兼容性

    • 文件夹上传需要使用webkitdirectory属性,但IE不支持
    • 最终解决方案:告诉客户"升级浏览器或使用Chrome框架"
  2. 大文件处理

    • 20G文件不能一次性读取到内存,必须分块
    • 使用了File API的slice方法实现分块
  3. 断点续传

    • 使用localStorage/cookie存储上传进度(IE9兼容方案)
    • 实际项目中应该使用IndexedDB或后端存储
  4. 加密传输

    • 使用了crypto-js库实现AES加密(但客户预算100元买不起库)
    • 最终解决方案:让后端同学实现加密
  5. 文件夹结构保留

    • 使用webkitRelativePath获取文件相对路径
    • 构建树形结构存储文件夹层级

真诚建议

各位同行,遇到这种项目请慎重考虑:

  1. 100元预算连买杯星巴克都不够
  2. 免费维护3年?不如直接让我给你打工
  3. 20G文件传输在浏览器端实现?这是要发明新的互联网协议吗?

加入我们的接单群

虽然这个项目让我掉了一把头发,但我还是决定继续在前端这条路上走下去。欢迎加入我们的接单群:374992201

群内福利:

  • 加群送1-99元红包
  • 推荐项目拿20%提成
  • 超级会员享50%提成
  • 不定期分享技术资源和接单技巧

最后说一句:前端不易,且行且珍惜。如果这个项目能做下来,我考虑转行去卖生发液了…

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

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

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

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

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

相关文章

c#编程文档翻译推荐:Hunyuan-MT-7B-WEBUI精准转换技术术语

C#编程文档翻译推荐&#xff1a;Hunyuan-MT-7B-WEBUI精准转换技术术语 在企业级软件开发日益全球化的今天&#xff0c;一个现实问题摆在每个.NET团队面前&#xff1a;如何让中文撰写的C#技术文档被世界各地的开发者准确理解&#xff1f;尤其当项目涉及异步编程、委托事件机制或…

比手动快10倍!自动化解决PRINT SPOOLER问题

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个高效的PRINT SPOOLER问题自动化解决工具&#xff0c;要求&#xff1a;1. 在30秒内完成问题诊断&#xff1b;2. 提供一键修复功能&#xff1b;3. 自动备份关键系统配置&…

(6-3)自动驾驶中的全局路径精简计算:Floyd算法的改进

6.3 Floyd算法的改进Floyd算法是一种用于解决图中任意两点间最短路径问题的经典算法。为了提高其效率和性能&#xff0c;可以采用多种优化改进方式。其中包括空间优化、提前终止、并行化计算、路径记忆、稀疏图优化等。这些优化改进方式可以单独或组合使用&#xff0c;以适应不…

/root目录找不到1键启动.sh?文件缺失原因及修复方式

/root目录找不到1键启动.sh&#xff1f;文件缺失原因及修复方式 在部署AI模型时&#xff0c;最让人头疼的不是复杂的算法调优&#xff0c;而是卡在“第一步”——连服务都启动不了。最近不少用户反馈&#xff0c;在使用腾讯混元&#xff08;Hunyuan&#xff09;推出的 Hunyuan-…

新能源车充电桩状态识别:远程监控使用情况

新能源车充电桩状态识别&#xff1a;远程监控使用情况 随着新能源汽车保有量的快速增长&#xff0c;充电基础设施的智能化管理成为城市智慧交通系统的重要组成部分。在实际运营中&#xff0c;如何实时掌握充电桩的使用状态——是空闲、正在充电、故障还是被非电动车占用——直接…

白细胞介素4(IL-4)的生物学功能与检测应用

一、IL-4的基本特性与历史发展是什么&#xff1f; 白细胞介素4&#xff08;Interleukin-4&#xff0c;IL-4&#xff09;是趋化因子家族中的关键细胞因子&#xff0c;由活化的T细胞、嗜碱性粒细胞和肥大细胞等多种免疫细胞产生。其发现历史可追溯至1982年&#xff0c;Howard等研…

Hunyuan-MT-7B-WEBUI开发者文档编写规范

Hunyuan-MT-7B-WEBUI开发者文档编写规范 在当今全球化加速推进的背景下&#xff0c;跨语言沟通早已不再是少数领域的专属需求。从跨境电商到国际教育&#xff0c;从多语种内容平台到民族语言保护&#xff0c;高质量、低门槛的机器翻译能力正成为基础设施级的技术支撑。然而现实…

12GB显存也能玩:FluxGym镜像快速搭建物体识别训练环境

12GB显存也能玩&#xff1a;FluxGym镜像快速搭建物体识别训练环境 作为一名业余AI爱好者&#xff0c;我一直想尝试修改开源物体识别模型来满足自己的需求。但手头的显卡只有12GB显存&#xff0c;直接跑训练经常遇到显存不足的问题。直到发现了FluxGym这个优化过的训练环境镜像&…

每10分钟更新一次的实时卫星影像

我们在《重大发现&#xff01;竟然可以下载当天拍摄的卫星影像》一文中&#xff0c;为大家分享了一个可以查看下载高时效卫星影像的方法。 这里再为大家推荐一个可以查看近乎实时的卫星影像的网站&#xff0c;卫星影像每10分钟更新一次。 实时卫星影像 打开网站&#xff08;…

Hunyuan-MT-7B模型镜像下载地址分享(附一键启动脚本)

Hunyuan-MT-7B模型镜像下载地址分享&#xff08;附一键启动脚本&#xff09; 在多语言内容爆炸式增长的今天&#xff0c;一个能快速部署、开箱即用的高质量翻译系统&#xff0c;几乎成了科研、教育和企业出海场景中的“刚需”。然而现实却常令人头疼&#xff1a;大多数开源翻译…

Hunyuan-MT-7B-WEBUI pull request 审核流程

Hunyuan-MT-7B-WEBUI&#xff1a;如何让高性能翻译模型真正“用起来” 在企业全球化加速、跨语言协作日益频繁的今天&#xff0c;机器翻译早已不再是实验室里的概念玩具。从跨境电商的产品描述自动本地化&#xff0c;到科研团队处理多语种文献&#xff0c;再到边疆地区公共服务…

从需求到成品:智能轮椅开发实战记录

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发智能轮椅控制系统原型&#xff0c;功能要求&#xff1a;1. 基于Arduino的电机控制模块 2. 手机蓝牙控制界面 3. 障碍物检测预警 4. 速度调节功能 5. 电池状态监控。请生成包含…

揭秘MCP网络异常:如何快速定位并解决IP冲突难题

第一章&#xff1a;MCP网络异常概述 在现代分布式系统架构中&#xff0c;MCP&#xff08;Microservice Communication Protocol&#xff09;作为微服务间通信的核心协议&#xff0c;其稳定性直接影响系统的可用性与响应性能。当MCP网络出现异常时&#xff0c;通常表现为服务调用…

教学实践:用云端GPU带学生体验万物识别技术

教学实践&#xff1a;用云端GPU带学生体验万物识别技术 作为一名计算机教师&#xff0c;我经常遇到一个难题&#xff1a;如何让没有高性能电脑的学生也能亲身体验AI图像识别的魅力&#xff1f;实验室的电脑配置不足&#xff0c;难以运行复杂的深度学习模型。经过多次尝试&#…

企业官网首屏如何3分钟生成?快马AI建站实战

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个响应式企业官网首页HTML模板&#xff0c;包含&#xff1a;1.固定在顶部的导航栏(logo5个菜单项) 2.全屏英雄区域(背景图主标题副标题CTA按钮) 3.三栏特色服务区 4.页脚联系…

yolov8 vs 万物识别-中文通用:目标检测精度与速度对比

YOLOv8 vs 万物识别-中文通用&#xff1a;目标检测精度与速度对比 引言&#xff1a;为何需要一次深度对比&#xff1f; 在当前智能视觉应用快速落地的背景下&#xff0c;目标检测技术已成为图像理解的核心能力之一。YOLOv8作为Ultralytics推出的高效单阶段检测器&#xff0c;在…

1小时搞定:用快马平台快速搭建优先队列DEMO

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请快速生成一个任务调度系统的优先队列原型&#xff0c;要求&#xff1a;1.支持任务优先级动态调整 2.可视化任务队列状态 3.模拟任务执行过程 4.提供REST API接口 5.包含简单的We…

一键部署万物识别API:无需编程的AI图像分析解决方案

一键部署万物识别API&#xff1a;无需编程的AI图像分析解决方案 作为产品经理&#xff0c;你是否遇到过这样的困境&#xff1a;想评估AI图像识别技术在产品中的应用潜力&#xff0c;但团队缺乏专业的AI开发人员&#xff1f;本文将介绍一种无需深入技术细节的快速验证方案——通…

零信任落地难?MCP安全测试实战经验,助你突破防护瓶颈

第一章&#xff1a;零信任落地难&#xff1f;MCP安全测试实战经验&#xff0c;助你突破防护瓶颈在企业推进零信任架构的过程中&#xff0c;策略执行与持续验证常因环境复杂而难以落地。微隔离控制点&#xff08;MCP&#xff09;作为实现细粒度访问控制的核心组件&#xff0c;其…

万物识别联邦学习:分布式训练环境快速搭建

万物识别联邦学习&#xff1a;分布式训练环境快速搭建 联邦学习作为一种新兴的机器学习范式&#xff0c;能够在保护数据隐私的前提下实现多方协作训练。对于医疗团队而言&#xff0c;使用联邦学习训练万物识别模型可以避免敏感数据外泄&#xff0c;同时提升模型识别能力。本文将…