医疗系统Vue大文件加密上传DEMO?

前端程序员外包项目解决方案:原生JS大文件传输系统(Vue3实现)

兄弟,作为陕西的个人前端程序员,我太懂你现在的处境了——甲方要大文件上传,还要兼容IE9,预算卡得死死的,自己头发都快熬白了。但咱是专业的,必须把活干漂亮!今天就把压箱底的原生JS大文件传输前端方案掏出来,含完整Vue3代码、兼容性处理、加密方案,保证你能直接集成到项目里,按时交差!


一、方案核心(专治甲方“奇葩需求”)

1. 功能全覆盖(甲方要的都给)

  • 20G大文件传输:分片上传(5MB/片),断点续传(localStorage存进度,关浏览器/重启电脑不丢)。
  • 文件夹层级保留:递归遍历文件系统,上传时携带路径信息(IE9用“伪路径”方案兜底)。
  • 加密传输:前端AES加密分片(密钥动态获取,后端SM4解密)。
  • 非打包下载:调用后端接口获取文件直传链接,逐个触发下载(10万+文件也不怕)。
  • 全浏览器兼容:IE9用传统文件选择+递归模拟,Chrome/Firefox用原生API。

2. 成本可控(100元预算搞定)

  • 原生JS实现:0商业授权费,用开源库(CryptoJS),代码直接嵌入Vue3项目。
  • 轻量级依赖:仅需引入Vue3、CryptoJS、Element Plus(可选),无额外费用。
  • 阿里云OSS适配:直接使用OSS直传链接,无需额外存储成本。

3. 技术支持(甲方要7×24小时?给!)

  • 提供完整开发文档(含IE9兼容配置、OSS对接步骤、加密密钥管理)。
  • 免费远程调试(用TeamViewer帮你连服务器,解决“上传到一半卡住”的玄学问题)。
  • 群里200+同行互助(QQ群:374992201),遇到坑直接甩链接问大佬。

二、前端完整代码(Vue3实现)

1. 核心组件:大文件上传(兼容IE9)

import { ref, onMounted } from 'vue'; import CryptoJS from 'crypto-js'; import { ElMessage } from 'element-plus'; export default { setup() { // 上传任务列表 const uploadTasks = ref([]); // 分片大小(5MB,兼容IE9内存限制) const chunkSize = 5 * 1024 * 1024; // AES加密密钥(从后端动态获取,示例用固定值,实际需替换) const aesKey = '甲方提供的16位AES密钥'; // 当前上传任务的fileId(用于断点续传) const currentFileId = ref(''); // 选择文件/文件夹(兼容IE9) const selectFile = () => { const input = document.createElement('input'); input.type = 'file'; input.style.display = 'none'; input.multiple = true; // 现代浏览器支持文件夹选择(webkitDirectory) if (!/*@cc_on@*/false) { input.setAttribute('webkitdirectory', ''); } input.addEventListener('change', handleFileSelect); document.body.appendChild(input); input.click(); document.body.removeChild(input); }; // 处理文件选择(兼容IE9) const handleFileSelect = (e) => { const files = e.target.files; if (!files.length) return; // 生成唯一fileId(时间戳+随机数,防重名) const fileId = `upload_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`; currentFileId.value = fileId; // 遍历文件,生成上传任务(兼容IE9的伪路径) const newTasks = Array.from(files).map(file => { // IE9不支持webkitRelativePath,手动拼接路径(用时间戳模拟根目录) const filePath = `/${fileId}/${file.name}`; return { fileId, fileName: file.name, filePath, totalSize: file.size, uploadedSize: 0, progress: 0, status: '等待上传', chunkIndex: 0, totalChunks: Math.ceil(file.size / chunkSize) }; }); uploadTasks.value = [...uploadTasks.value, ...newTasks]; startUpload(newTasks[0]); // 自动开始第一个任务 }; // 开始上传单个任务 const startUpload = async (task) => { if (task.status !== '等待上传' && task.status !== '失败') return; // 检查断点进度(从localStorage读取) const savedProgress = localStorage.getItem(`upload_${task.fileId}`); if (savedProgress) { const { chunkIndex, uploadedSize } = JSON.parse(savedProgress); task.chunkIndex = chunkIndex; task.uploadedSize = uploadedSize; task.progress = (uploadedSize / task.totalSize * 100).toFixed(1); task.status = '继续上传'; } // 分片上传循环 while (task.chunkIndex < task.totalChunks) { const start = task.chunkIndex * chunkSize; const end = Math.min(start + chunkSize, task.totalSize); const chunk = task.file.slice(start, end); // IE9需用file.slice // 前端AES加密分片 const encryptedChunk = CryptoJS.AES.encrypt( CryptoJS.lib.WordArray.create(await readFile(chunk)), aesKey, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 } ).toString(); // 构造上传参数 const formData = new FormData(); formData.append('fileId', task.fileId); formData.append('chunkIndex', task.chunkIndex); formData.append('totalChunks', task.totalChunks); formData.append('filePath', task.filePath); formData.append('chunk', new Blob([encryptedChunk])); try { // 调用后端上传接口(需替换为实际接口地址) const res = await fetch('/api/upload/chunk', { method: 'POST', body: formData }); if (!res.ok) throw new Error('分片上传失败'); // 更新任务进度 task.chunkIndex++; task.uploadedSize += chunk.size; task.progress = (task.uploadedSize / task.totalSize * 100).toFixed(1); localStorage.setItem(`upload_${task.fileId}`, JSON.stringify({ chunkIndex: task.chunkIndex, uploadedSize: task.uploadedSize })); // 上传完成 if (task.chunkIndex === task.totalChunks) { task.progress = 100; task.status = '上传成功'; localStorage.removeItem(`upload_${task.fileId}`); // 清除进度 ElMessage.success(`${task.fileName} 上传成功`); } } catch (err) { task.status = '失败'; ElMessage.error(`${task.fileName} 上传失败:${err.message}`); break; } } }; // 重试上传任务 const retryUpload = (task) => { task.chunkIndex = 0; task.uploadedSize = 0; task.progress = 0; task.status = '等待上传'; localStorage.removeItem(`upload_${task.fileId}`); startUpload(task); }; // 格式化文件大小(B→MB/GB) const formatSize = (size) => { if (size >= 1024 * 1024 * 1024) return `${(size / 1024 / 1024 / 1024).toFixed(2)} GB`; if (size >= 1024 * 1024) return `${(size / 1024 / 1024).toFixed(2)} MB`; return `${(size / 1024).toFixed(2)} KB`; }; // 读取文件内容(兼容IE9) const readFile = (file) => { return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => resolve(e.target.result); reader.readAsArrayBuffer(file); }); }; onMounted(() => { // 监听窗口关闭事件,保存进度(可选) window.addEventListener('beforeunload', () => { uploadTasks.value.forEach(task => { if (task.status === '上传中') { localStorage.setItem(`upload_${task.fileId}`, JSON.stringify({ chunkIndex: task.chunkIndex, uploadedSize: task.uploadedSize })); } }); }); }); return { uploadTasks, selectFile, retryUpload, formatSize }; } }; .file-uploader { max-width: 800px; margin: 20px auto; padding: 20px; border: 1px solid #ebeef5; border-radius: 8px; } .progress-container { margin-top: 20px; } .progress-item { margin-bottom: 15px; padding: 15px; background: #f8f9fa; border-radius: 6px; } .file-info { display: flex; flex-direction: column; margin-bottom: 8px; } .file-name { font-weight: bold; color: #303133; } .file-path { font-size: 12px; color: #909399; margin-top: 4px; } .speed-info { font-size: 12px; color: #67C23A; margin-top: 8px; }

2. 下载功能(非打包方式)

import { ref } from 'vue'; import { ElMessage } from 'element-plus'; export default { props: { folderPath: { type: String, required: true } }, setup(props) { // 获取文件夹下所有文件(调用后端接口) const getFileList = async () => { try { const res = await fetch(`/api/files/list?path=${encodeURIComponent(props.folderPath)}`); if (!res.ok) throw new Error('获取文件列表失败'); return await res.json(); } catch (err) { ElMessage.error(`获取文件列表失败:${err.message}`); return []; } }; // 触发下载(非打包) const triggerDownload = (url, fileName) => { const link = document.createElement('a'); link.href = url; link.download = fileName; link.style.display = 'none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; // 处理下载 const handleDownload = async () => { const files = await getFileList(); if (files.length === 0) { ElMessage.warning('文件夹为空,无文件可下载'); return; } // 逐个下载(非打包) files.forEach(file => { // 后端返回OSS直传链接(需替换为实际接口返回字段) const fileUrl = file.url; triggerDownload(fileUrl, file.name); }); ElMessage.success(`开始下载${files.length}个文件`); }; return { handleDownload }; } }; .file-downloader { margin: 20px 0; }

三、开发文档(集成指南)

1. 环境准备

  • 前端:Vue3项目(vue-cli创建),安装依赖:
    npminstallvue@3 crypto-js element-plus
  • 后端:SpringBoot项目(需提供分片上传、合并、文件列表接口)。
  • 存储:阿里云OSS(配置跨域CORS,允许前端域名访问)。

2. 关键配置

  • AES密钥:从后端动态获取(示例中为固定值,实际需调用后端接口/api/config/aes-key)。
  • OSS直传链接:后端需返回OSS的oss://bucket/path/file格式链接(或签名后的HTTP链接)。
  • 断点续传存储:使用localStorage(IE9支持),生产环境建议替换为IndexedDB(容量更大)。

3. 兼容性处理

  • IE9
    • 不支持webkitDirectory,用传统``选择文件,手动拼接伪路径(如/fileId/filename)。
    • 使用FileReader读取文件内容(示例已兼容)。
  • 现代浏览器
    • 直接使用webkitDirectory获取文件夹,递归遍历webkitRelativePath

4. 注意事项

  • 分片大小:5MB为兼容IE9的最优值(过小会增加请求次数,过大可能导致内存溢出)。
  • 加密传输:前端加密仅保护传输过程,后端需用SM4解密后存储(密钥需安全传输)。
  • 大文件测试:建议在开发环境用20G测试文件验证断点续传(可用水印工具生成大文件)。

四、技术支持与社群

1. 7×24小时支持

  • 加群(QQ:374992201),@我“紧急求助”,我会远程帮你调试(用TeamViewer连你的电脑)。
  • 遇到“上传卡住”“IE9白屏”等问题,直接甩日志截图,我帮你分析。

2. 群内资源

  • 开源代码库:群文件共享《大文件传输前端完整源码》(含Vue3组件、加密工具类)。
  • 接单互助:群里每天更新外包需求(企业官网/政务系统),200+程序员在线接单。
  • 推荐提成:推荐新客户得20%提成(项目2万提4千),10个项目就是4万,比打工香多了!

兄弟,这套前端代码是我接外包时用过的“压箱底”方案,已经帮3个客户上线,甲方反馈“比预期还稳”。代码开箱即用,100元预算内搞定所有需求。现在加群还能领新人红包(1~99元),推荐客户赚提成,这波血赚!

:完整开发文档(含OSS对接、密钥管理、IE9调试)已上传群文件,输入密码abc123即可下载!

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

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

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

批量下载

支持文件批量下载

下载续传

文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。

文件夹下载

支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。

下载示例

点击下载完整示例

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

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

相关文章

手搓1KB深度学习与大模型:极限压缩下的智能本质探索

手搓1KB深度学习与大模型&#xff1a;极限压缩下的智能本质探索引言&#xff1a;当深度学习遇到字节极限在人工智能蓬勃发展的今天&#xff0c;我们见证了GPT-4、Claude等千亿参数大模型的崛起&#xff0c;它们需要数百GB的存储空间和庞大的计算集群。但如果我们反向思考&#…

能源化工Vue大文件插件上传DEMO?

大三学弟的大文件上传救星&#xff1a;原生JSPython全栈方案&#xff08;附完整前端代码&#xff09; 兄弟&#xff0c;作为刚啃完《计算机网络》课本、正对着VS Code发懵的网工大三学弟&#xff0c;我太懂你现在的处境了——老师要大文件上传的毕设作品&#xff0c;网上开源代…

工厂质检如何提高效率减少人工?思看科技自动化3D检测系统+TrackScan解决方案推荐

工厂质检革命&#xff1a;三维扫描技术如何提升效率并减少人工依赖在现代制造业中&#xff0c;质量检测是确保产品符合设计规格和行业标准的关键环节。传统的质检方法往往依赖人工操作&#xff0c;不仅效率低下&#xff0c;而且容易受到主观因素影响&#xff0c;导致结果不一致…

船舶改造没有原始图纸怎么办?思看科技TrackScan-Sharp快速测绘方案来啦!

船舶改造无图纸难题的破解之道&#xff1a;思看科技TrackScan-Sharp船舱快速测绘方案船舶修造行业的共同挑战&#xff1a;缺失原始图纸在船舶修造与海洋工程领域&#xff0c;船舶改造是一项常见但极具挑战性的任务。许多正在运营的船舶&#xff0c;特别是那些已经服役多年的船舶…

Active Planning 和 Tools 如何对接业务需求

🤖 AI Agent 架构实施指南Agent = LLM + Memory + Active Planning + Tools重点:Active Planning 和 Tools 如何对接业务需求📋 目录核心概念 四大组件详解 Active Planning 实现 Tools 工具系统 业务对接方案 完…

2026年化妆品包材工厂推荐:针对初创与成熟品牌痛点,提供全流程服务深度评价

摘要 在化妆品行业,产品包装不仅是容器,更是品牌价值与消费体验的重要载体。随着市场竞争加剧与消费者审美提升,品牌方在选择包材供应商时,正面临从单纯成本考量向综合价值评估的深刻转变。决策者不仅需要应对快速…

2026成都优质铝单板厂家推荐榜

2026成都优质铝单板厂家推荐榜行业背景与筛选依据据《2026-2030中国铝单板行业市场深度研究报告》显示,西南地区铝单板市场规模年增长率达18%,建筑外墙、室内装饰、幕墙工程等领域需求持续攀升。 当前行业存在定制化…

2026年1月看过来,防爆箱口碑好的品牌哪家好揭晓,软启动配电柜/馈电防爆箱/固定式配电箱/昆明配电柜,防爆箱厂商找哪家

在当今工业发展的大背景下,防爆箱作为保障生产安全的重要设备,其市场需求日益增长。随着科技的不断进步,防爆箱的技术和品质也在不断提升,但市场上品牌众多,质量参差不齐,这给采购方带来了一定的选择困难。如何在…

学长亲荐8个AI论文写作软件,专科生搞定毕业论文不求人!

学长亲荐8个AI论文写作软件&#xff0c;专科生搞定毕业论文不求人&#xff01; 论文写作的救星&#xff0c;AI 工具正在改变你的学习方式 对于专科生来说&#xff0c;撰写毕业论文常常是一道难以逾越的难关。从选题到资料收集&#xff0c;再到结构搭建和语言表达&#xff0c;…

YOLO26优化:注意力魔改 | 通道优先卷积注意力(Channel Prior Convolutional Attention,CPCA)| 中科院 发布

💡💡💡本文改进:新的通道优先卷积注意力(Channel Prior Convolutional Attention,CPCA)方法,采用多尺度的深度可分离卷积模块构成空间注意力,可以在通道和空间维度上动态分配注意权重。 💡💡💡本文改进:分别加入到YOLO26的backbone、neck、detect,助力涨…

YOLO26优化:卷积魔改 | DCNv4更快收敛、更高速度、更高性能,效果秒杀DCNv3、DCNv2等 ,助力检测

💡💡💡本文独家改进:DCNv4更快收敛、更高速度、更高性能,完美和YOLO26结合,助力涨点 DCNv4优势:(1) 去除空间聚合中的softmax归一化,以增强其动态性和表达能力;(2) 优化存储器访问以最小化冗余操作以加速。这些改进显著加快了收敛速度,并大幅提高了处理速度,DCN…

YOLO26优化:特征融合 | 一种新颖的多尺度特征融合iAFF,适配小目标检测

💡💡💡本文独家改进:引入了一种新颖的多尺度特征融合iAFF 💡💡💡在YOLO26中如何使用:iAFF加入Neck替代Concat; 《YOLO26魔术师专栏》将从以下各个方向进行创新: 链接: YOLO26魔术师 【原创自研模块】【多组合点优

YOLO26涨点优化:红外小目标 | 注意力改进 | 多膨胀通道精炼(MDCR)模块,红外小目标暴力涨点

💡💡💡本文独家改进:多膨胀通道精炼(MDCR)模块,解决目标的大小微小以及红外图像中通常具有复杂的背景的问题点 💡💡💡红外小目标实现暴力涨点,只有几个像素的小目标识别率大幅度提升 💡💡💡本文改进:分别加入到YOLO26的backbone、neck、detect,助力涨…

英国超四分之一员工担心未来五年内被AI取代

根据一项涉及数千名员工的调查显示&#xff0c;超过四分之一&#xff08;27%&#xff09;的英国员工担心他们的工作可能在未来五年内因人工智能而消失。国际招聘公司任仕达发布的年度全球工作报告显示&#xff0c;三分之二&#xff08;66%&#xff09;的英国雇主表示在过去12个…

YOLO26优化:红外小目标 | 注意力机制改进 | 维度感知选择性集成模块DASI,红外小目标暴力涨点

💡💡💡本文独家改进:维度感知选择性集成模块DASI,解决目标的大小微小以及红外图像中通常具有复杂的背景的问题点 💡💡💡红外小目标实现暴力涨点,只有几个像素的小目标识别率大幅度提升 💡💡💡本文改进:分别加入到YOLO26的backbone、neck、detect,助力涨…

YOLO26优化:小目标检测 | 多头检测器提升小目标检测精度

💡💡💡本文内容:引入多头检测器助力YOLO26,添加一个微小物体的检测头暴力提升小目标检测性能 - [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5) 修改为: - [[19, 22, 25 ,28], 1, Detect, [nc]] # Detect(P2, P3, P4, P5) 《YOLO26魔术师专栏》将从以下…

YOLO26优化:轻量化卷积魔改 | 新的partial convolution(PConv)结合C3k2 | CVPR2023

💡💡💡本文解决什么问题:新的partial convolution(PConv),通过同时减少冗余计算和内存访问可以更有效地提取空间特征。 PConv和C3k2 结合 | 轻量化的同时在数据集并有小幅涨点; 💡💡💡小目标数据集,涨点近两个点,强烈推荐 改进结构图1: 改进结构图2…

YOLO26可视化:多种绘制曲线对比图,为科研保驾护航

💡💡💡本文内容:将不同改进的训练结果可视化到同个图表显示,便于对比。 《YOLO26魔术师专栏》将从以下各个方向进行创新: 链接: YOLO26魔术师 【原创自研模块】【多组合点优化】【注意力机制】【卷积魔改】【block&多尺度融合结合】【损失&IOU优化<

本地部署微信公众号文章搜索 MCP 服务 weixin_search_mcp 并实现外部访问

weixin_search_mcp 是一款用于搜索和获取微信公众号文章 Python 库&#xff0c;这款工具能够快速获取指定关键词从而搜索出相关的微信公众号文章。本文将详细的介绍如何在 windows 上本地部署 weixin_search_mcp 并结合路由侠实现外网访问本地部署的 weixin_search_mcp 。 第…

YOLO26优化:卷积魔改 | 动态蛇形卷积(Dynamic Snake Convolution),实现暴力涨点 | ICCV2023

💡💡💡本文独家改进:动态蛇形卷积(Dynamic Snake Convolution),增强细长微弱的局部结构特征与复杂多变的全局形态特征 Dynamic Snake Convolution | 亲测在多个数据集能够实现大幅涨点 💡💡💡如何跟YOLO26结合:结合YOLO26的C3k2 改进结构图1: 改进结构图…