news 2026/3/26 13:08:25

html5大文件上传插件的加密传输原理与实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
html5大文件上传插件的加密传输原理与实现

一个前端菜鸟的大文件上传奋斗史

大家好,我是一个在浙江某大学网络工程专业摸爬滚打的大三狗🐶,最近被一个"小小的"文件管理系统项目折磨得死去活来…

我的"简单"需求清单 📝

  1. 文件上传:不就是传个文件吗?简单!等等…10G的文件??
  2. 文件夹上传:要保留层级结构的那种哦~
  3. 断点续传:关了浏览器、重启电脑都不能丢进度!
  4. 加密传输:不能让隔壁寝室的小王偷看我的学习资料🔒
  5. 浏览器兼容:从IE8到各种国产浏览器,一个都不能少!

我的技术栈 🤹

  • 前端:Vue3 + 原生JS(老师说要锻炼基础)
  • 开发工具:VSCode(配色必须用暗黑主题才显得专业)
  • 后端:Python(刚学,目前只会print(“Hello World”))
  • 数据库:MySQL(只会简单的增删改查)
  • 服务器:先放我F盘,等有钱了再搞个CentOS虚拟机

我的血泪史 😭

在网上找了一圈代码,不是功能不全就是根本跑不起来!那些开发者连个联系方式都不留,出了bug只能自求多福。我寻思着,这代码写得跟薛定谔的猫似的——你不运行就不知道它能不能用!

于是我一怒之下建了个QQ群(374992201),欢迎同是天涯沦落人的小伙伴们加入。新人入群送1-99元红包(99元的那个红包我还没见过长啥样),还有各种"超级会员"、"代理商"头衔等你来拿!(其实就是大家一起互相折磨罢了)

前端代码实现(Vue3版) 🚀

1. 大文件分片上传核心逻辑

// FileUploader.vueexportdefault{data(){return{fileList:[],folderList:[],chunkSize:5*1024*1024,// 5MB一个分片maxRetries:3,// 最大重试次数uploadProgress:{},// 上传进度resumeData:JSON.parse(localStorage.getItem('uploadResumeData'))||{}// 断点续传数据}},methods:{// 处理文件选择handleFileChange(e){constfiles=Array.from(e.target.files)files.forEach(file=>{// 10GB文件限制检查if(file.size>10*1024*1024*1024){alert('文件大小超过10GB限制!')return}this.fileList.push(this.prepareFile(file))})},// 准备文件对象prepareFile(file){return{id:this.generateFileId(file),file,name:file.name,size:file.size,type:file.type,chunks:Math.ceil(file.size/this.chunkSize),uploadedChunks:0,status:'pending',encrypted:false}},// 生成唯一文件IDgenerateFileId(file){returnfile.name+'_'+file.size+'_'+file.lastModified},// 开始上传asyncstartUpload(){for(constfileObjofthis.fileList){if(fileObj.status==='completed')continuefileObj.status='uploading'awaitthis.uploadFile(fileObj)}},// 文件分片上传asyncuploadFile(fileObj){const{file,id,chunks}=fileObjfor(leti=0;i<chunks;i++){// 检查是否已经上传过该分片if(this.resumeData[id]?.includes(i)){fileObj.uploadedChunks++this.updateProgress(fileObj)continue}constchunk=this.getFileChunk(file,i)constformData=newFormData()formData.append('file',chunk)formData.append('chunkIndex',i)formData.append('totalChunks',chunks)formData.append('fileId',id)formData.append('fileName',file.name)letretries=0letsuccess=false// 重试机制while(retries<this.maxRetries&&!success){try{awaitthis.uploadChunk(formData)success=true// 更新断点续传数据if(!this.resumeData[id]){this.resumeData[id]=[]}this.resumeData[id].push(i)localStorage.setItem('uploadResumeData',JSON.stringify(this.resumeData))fileObj.uploadedChunks++this.updateProgress(fileObj)}catch(error){retries++if(retries===this.maxRetries){fileObj.status='error'console.error(`分片${i}上传失败:`,error)}}}}if(fileObj.uploadedChunks===chunks){fileObj.status='completed'// 通知后端合并文件awaitthis.mergeFile(fileObj)}},// 获取文件分片getFileChunk(file,chunkIndex){conststart=chunkIndex*this.chunkSizeconstend=Math.min(file.size,start+this.chunkSize)returnfile.slice(start,end)},// 更新进度updateProgress(fileObj){constprogress=Math.round((fileObj.uploadedChunks/fileObj.chunks)*100)this.uploadProgress[fileObj.id]=progressthis.$forceUpdate()},// 上传分片(实际请求需要根据后端实现)uploadChunk(formData){returnnewPromise((resolve,reject)=>{constxhr=newXMLHttpRequest()xhr.open('POST','/api/upload/chunk',true)xhr.onload=()=>{if(xhr.status>=200&&xhr.status<300){resolve(xhr.response)}else{reject(xhr.statusText)}}xhr.onerror=()=>reject('Network error')xhr.send(formData)})},// 合并文件(实际请求需要根据后端实现)mergeFile(fileObj){returnfetch('/api/upload/merge',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({fileId:fileObj.id,fileName:fileObj.name,totalChunks:fileObj.chunks})})},// 文件夹上传处理handleFolderUpload(e){constitems=e.dataTransfer?.items||e.target.filesthis.processFolderItems(items)},// 递归处理文件夹内容asyncprocessFolderItems(items,path=''){for(leti=0;i<items.length;i++){constentry=items[i].webkitGetAsEntry?.()||items[i]if(entry.isFile){entry.file(file=>{constfileObj=this.prepareFile(file)fileObj.path=paththis.fileList.push(fileObj)})}elseif(entry.isDirectory){constdirReader=entry.createReader()dirReader.readEntries(entries=>{this.processFolderItems(entries,`${path}${entry.name}/`)})}}},// 简单加密函数(演示用,实际应该使用更强大的加密算法)simpleEncrypt(data){// 这里应该使用Web Crypto API或其他加密库// 仅为演示,实际项目中请勿使用这种简单加密returnbtoa(unescape(encodeURIComponent(data)))}}}

2. 兼容IE8的polyfills和hack 💩

// polyfills.js// 兼容IE8的File API polyfillif(typeofFile==='undefined'){functionFile(){// 简陋的模拟实现}}// 兼容IE8的Blob polyfillif(typeofBlob==='undefined'){functionBlob(){// 简陋的模拟实现}}// 兼容IE8的FormData polyfillif(typeofFormData==='undefined'){functionFormData(){this.data=[]this.append=function(key,value){this.data.push({key:key,value:value})}}}// 兼容旧版浏览器的requestAnimationFrameif(!window.requestAnimationFrame){window.requestAnimationFrame=function(callback){returnsetTimeout(callback,1000/60)}}// 兼容旧版浏览器的fetch APIif(!window.fetch){window.fetch=function(url,options){returnnewPromise(function(resolve,reject){varxhr=newXMLHttpRequest()xhr.open(options.method||'GET',url)if(options.headers){Object.keys(options.headers).forEach(function(key){xhr.setRequestHeader(key,options.headers[key])})}xhr.onload=function(){resolve({status:xhr.status,json:function(){returnPromise.resolve(JSON.parse(xhr.responseText))},text:function(){returnPromise.resolve(xhr.responseText)}})}xhr.onerror=reject xhr.send(options.body)})}}

我的卑微请求 🙏

  1. 求后端大佬:有没有Python后端大佬愿意带带我?我可以用我的毕设成果(如果我能做出来的话)回报您!

  2. 求工作推荐:马上要毕业了,有师哥师姐在招人吗?我要求不高,能给口饭吃就行(最好能顺便教教我后端)。

  3. 求学习伙伴:加我QQ群374992201,我们一起从入门到放弃,再从放弃到入门!

最后的小广告 🎤

加入我们群,你将获得:

  • 1-99元红包(99元的那位同学请私聊我领奖)
  • 一起学习的小伙伴(互相折磨到白头)
  • 可能的就业机会(等我们学会后互相内推)
  • 无限的快乐(看着别人和自己一样痛苦)

记住我们的口号:“今天不努力,明天做后端!”😂


免责声明:以上代码仅供参考,实际项目中请根据需求修改。作者不对因使用此代码导致的电脑爆炸、头发脱落、挂科等后果负责。

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

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

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

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

Markdown制作目录:长篇PyTorch教程结构化

长篇PyTorch教程的结构化实践&#xff1a;从容器环境到文档组织 在深度学习项目开发中&#xff0c;一个常见的痛点是——为什么同样的代码&#xff0c;在别人的机器上跑得飞快&#xff0c;而在自己这边却报错不断&#xff1f;更别提教学场景下&#xff0c;学生反复提问“CUDA不…

作者头像 李华
网站建设 2026/3/16 16:48:32

Anaconda Prompt执行PyTorch命令无响应?解决方案

Anaconda Prompt执行PyTorch命令无响应&#xff1f;解决方案 在深度学习项目开发中&#xff0c;一个看似简单的问题却可能让开发者耗费数小时&#xff1a;当你打开 Anaconda Prompt&#xff0c;输入 import torch&#xff0c;回车后光标只是不停闪烁——没有报错&#xff0c;也…

作者头像 李华
网站建设 2026/3/26 8:04:36

PyTorch-CUDA-v2.7镜像安全更新:修复CVE漏洞

PyTorch-CUDA-v2.7镜像安全更新&#xff1a;修复CVE漏洞 在深度学习工程实践中&#xff0c;一个看似微小的环境差异或未修复的安全漏洞&#xff0c;可能让整个训练任务暴露于风险之中——轻则导致模型结果无法复现&#xff0c;重则引发系统被入侵、数据泄露。近期发布的 PyTor…

作者头像 李华
网站建设 2026/3/14 13:38:41

GitHub Actions自动构建PyTorch镜像

GitHub Actions自动构建PyTorch镜像 在深度学习项目中&#xff0c;你是否经历过这样的场景&#xff1a;本地训练模型一切正常&#xff0c;推送到服务器后却因CUDA版本不匹配导致PyTorch无法识别GPU&#xff1f;或者新同事花了整整两天才把环境搭好&#xff0c;结果第一个pip in…

作者头像 李华
网站建设 2026/3/22 12:13:01

Vue3基于spring boot 与Vue的地方特色美食分享平台设计与实现(编号:94892387)

目录已开发项目效果实现截图关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;已开发…

作者头像 李华
网站建设 2026/3/4 3:50:28

Markdown写技术博客必备:用Jupyter+PyTorch展示代码效果

用 Jupyter PyTorch 让技术博客“活”起来 在 AI 内容爆炸式增长的今天&#xff0c;一篇技术博文是否真的有价值&#xff0c;往往不在于它讲了多少概念&#xff0c;而在于读者能否立刻验证、亲手运行、亲眼看到结果。静态的文字和截图早已无法满足深度学习时代的表达需求——…

作者头像 李华