news 2026/3/1 8:41:33

html5大文件分片上传插件vue-cli项目集成与加密传输

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
html5大文件分片上传插件vue-cli项目集成与加密传输

前端老兵的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

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/17 20:56:47

(支持 MCP 无状态集群)Solon AI MCP v3.8.0, v3.7.4,v3.6.7 发布

Solon AI & MCP&#xff08;支持 LTS&#xff09; Solon AI & MCP &#xff0c;是 Solon 官方推出的 Java 智能体应用开发框架。旨在为 Java 开发者提供统一的接口抽象层&#xff0c;简化与 OpenAI、DeepSeek、QWen 等主流 AI 模型的集成流程&#xff0c;以及简化 Mcp…

作者头像 李华
网站建设 2026/2/25 7:56:06

PaddlePaddle镜像在保险理赔图像定损中的自动化流程

PaddlePaddle镜像在保险理赔图像定损中的自动化流程 在车险理赔的日常处理中&#xff0c;一个看似简单的任务——查看客户上传的照片并判断车辆损伤程度——背后却隐藏着巨大的人力成本和效率瓶颈。传统流程中&#xff0c;每起案件需要专业定损员花费10到30分钟逐图分析&#…

作者头像 李华
网站建设 2026/2/27 16:21:16

PaddlePaddle模型保存与加载最佳实践

PaddlePaddle模型保存与加载最佳实践 在深度学习项目从实验走向生产的旅程中&#xff0c;一个常被低估但至关重要的环节浮出水面&#xff1a;模型如何可靠地“活下去”。训练再完美的模型&#xff0c;如果无法正确保存、稳定加载、高效部署&#xff0c;最终也只能停留在笔记本的…

作者头像 李华
网站建设 2026/3/1 7:20:14

10大AI测试工具:必备效率提升器

随着深度学习与生成式AI的突破性进展&#xff0c;2025年的软件测试领域正经历智能化变革。Gartner最新报告指出&#xff0c;采用AI工具的测试团队缺陷逃逸率降低43%&#xff0c;回归测试效率提升6.8倍。本文基于全球Top500企业实践案例&#xff0c;精选十大具有工程化落地价值的…

作者头像 李华
网站建设 2026/2/22 6:06:48

性能提升80%的背后,智谱Open-AutoGLM 2.0是如何重构AI工作流的?

第一章&#xff1a;性能提升80%的背后&#xff0c;智谱Open-AutoGLM 2.0是如何重构AI工作流的&#xff1f; 智谱Open-AutoGLM 2.0的发布标志着自动化自然语言处理工作流进入新阶段。其核心突破在于对任务调度、模型推理与数据预处理链路的深度优化&#xff0c;通过动态计算图重…

作者头像 李华