news 2026/3/24 0:06:39

百度WebUploader如何结合AES加密完成大附件加密传输?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
百度WebUploader如何结合AES加密完成大附件加密传输?

咱福州网工仔实锤了!最近为了毕设焦头烂额——要搞个能打的大文件管理系统,还要兼容IE8这种“上古浏览器”(学校机房那台Win7+IE9的老古董,点个按钮都像在玩心跳)。找了一圈后端教程,不是“自己悟”就是“付费课”,现在连后端代码都要自己摸着石头过河……今天先把前端代码整明白,至少毕设演示时能“表面光”!


前端目标:用原生JS+WebUploader,搞定10G上传+断点续传+文件夹

咱一个后端小白,后端Python还在啃《笨办法学Python》,所以前端必须“能跑能用”——核心就三点:

  1. 兼容老浏览器:IE8用Flash,IE9+用H5,龙芯/红莲花这些信创浏览器也能跑。
  2. 断点续传:关浏览器/重启电脑都不怕,进度信息存本地(localStorage)。
  3. 文件夹上传:保留层级结构(比如/课程设计/文件管理系统/代码),IE8手动输路径凑合用。

前端代码:Vue3 + WebUploader(附详细注释)

先上干货!以下是核心代码,包含文件选择、分片上传、断点查询、文件夹处理,注释写得贼详细,小白也能看懂。

1. 安装依赖(VS Code里操作)

首先得装WebUploader和加密库(AES加密用):

# 在项目根目录敲命令(Vue3用npm或yarn都行)npminstallwebuploader crypto-js --save
2. 前端组件代码(src/components/BigFileUpload.vue)
import SparkMD5 from 'spark-md5'; // 计算文件MD5(断点续传关键) import WebUploader from 'webuploader'; // 引入WebUploader库 import CryptoJS from 'crypto-js'; // AES加密库(传输加密) export default { data() { return { uploader: null, // WebUploader实例 progress: 0, // 上传进度百分比 isUploading: false, // 是否正在上传 currentFile: null, // 当前处理的文件 fileMd5: '', // 当前文件的MD5(唯一标识,用于断点) chunkSize: 2 * 1024 * 1024, // 分片大小2MB(10G分5000片) uploadedChunks: [], // 已上传的分片序号(从本地localStorage读) encryptKey: 'user-defined-key-123' // 加密密钥(实际项目要让用户输入!) }; }, mounted() { this.initUploader(); // 初始化上传组件 }, methods: { // 初始化WebUploader(兼容IE8的Flash模式) initUploader() { // 配置WebUploader(重点参数注释) this.uploader = WebUploader.create({ swf: '/static/webuploader/Uploader.swf', // Flash路径(IE8必须,需提前下载) server: '/api/upload/chunk', // 后端分片接收接口(Python写的,后面说) pick: '#filePicker', // 选择文件按钮 dnd: '#dndArea', // 拖拽区域 paste: document.body, // 粘贴上传(可选) chunked: true, // 开启分片上传(大文件必须) chunkSize: this.chunkSize, // 分片大小2MB compress: false, // 不压缩(大文件压缩会丢内容) fileNumLimit: 100, // 最多同时传100个文件(防崩溃) fileSizeLimit: 10 * 1024 * 1024 * 1024, // 单个文件最大10G accept: { title: 'All Files', extensions: '*' // 允许所有格式(按需改) }, // 自定义参数(传给后端) formData: { encrypt: 'true', // 告诉后端要加密传输 key: this.encryptKey // 加密密钥(实际让用户输入更安全) } }); // 绑定事件:文件加入队列时触发(计算MD5) this.uploader.on('fileQueued', (file) => { this.currentFile = file; this.progress = 0; this.uploadedChunks = []; // 重置已上传分片 this.calculateFileMd5(file); // 计算文件MD5(断点续传的核心) }); // 绑定事件:分片上传前(查询已上传的分片) this.uploader.on('uploadBeforeSend', (obj, data) => { data.md5 = this.fileMd5; // 传MD5给后端查进度 data.chunk = obj.chunk; // 当前分片序号(0开始) data.chunks = obj.chunks; // 总分片数 }); // 绑定事件:上传进度更新(实时显示进度条) this.uploader.on('uploadProgress', (file, percentage) => { this.progress = Math.round(percentage * 100); }); // 绑定事件:单个分片上传成功(记录已上传分片到localStorage) this.uploader.on('uploadSuccess', (file, response) => { if (response.code === 200) { const { chunk } = response.data; this.uploadedChunks.push(chunk); // 记录已上传的分片序号 localStorage.setItem(`upload_${this.fileMd5}`, JSON.stringify(this.uploadedChunks)); // 存本地防丢失 } }); // 绑定事件:全部分片上传完成(合并文件) this.uploader.on('uploadFinished', (file) => { this.isUploading = false; this.$message.success(`${file.name} 上传完成!`); // 清空本地存储的进度(可选) localStorage.removeItem(`upload_${this.fileMd5}`); }); // 绑定事件:上传出错(提示用户) this.uploader.on('error', (type) => { this.isUploading = false; let msg = ''; switch (type) { case 'F_EXCEED_SIZE': msg = '文件超过10G限制!'; break; case 'Q_EXCEED_NUM_LIMIT': msg = '同时上传的文件太多!'; break; default: msg = `上传失败:${type}`; } this.$message.error(msg); }); }, // 计算文件MD5(断点续传的唯一标识) calculateFileMd5(file) { const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; const chunks = Math.ceil(file.size / this.chunkSize); // 总分片数 const spark = new SparkMD5.ArrayBuffer(); const fileReader = new FileReader(); // 分片读取文件内容,计算MD5(大文件可能有点慢,耐心等) const loadNext = (currentChunk) => { const start = currentChunk * this.chunkSize; const end = Math.min(start + this.chunkSize, file.size); fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); }; fileReader.onload = (e) => { spark.append(e.target.result); // 累加当前分片内容 const currentChunk = Math.floor(e.target.result.byteLength / this.chunkSize); if (currentChunk < chunks - 1) { loadNext(currentChunk); } else { this.fileMd5 = spark.end(); // 所有分片读完,得到最终MD5 this.queryUploadedChunks(); // 查询后端已上传的分片 } }; loadNext(0); // 开始计算 }, // 查询后端已上传的分片(从localStorage或后端接口) async queryUploadedChunks() { try { // 先从localStorage找(防止关浏览器后进度丢失) const localChunks = localStorage.getItem(`upload_${this.fileMd5}`); if (localChunks) { this.uploadedChunks = JSON.parse(localChunks); } else { // 没本地记录,调后端接口查(Python接口返回已上传的分片序号) const res = await this.$http.get(`/api/upload/chunks?md5=${this.fileMd5}`); this.uploadedChunks = res.data.uploadedChunks || []; } // 告诉WebUploader跳过已上传的分片(关键!) this.uploader.options.chunkRetry = 0; // 失败不重试(已上传的分片跳过) this.uploader.upload(); // 开始上传 } catch (err) { console.error('查询已上传分片失败', err); this.$message.error('获取上传进度失败,请重试'); } }, // 开始上传 startUpload() { if (!this.currentFile) { this.$message.warning('请先选择文件或文件夹!'); return; } this.isUploading = true; this.uploader.upload(); }, // 暂停上传 pauseUpload() { this.uploader.stop(); this.isUploading = false; }, // 清空队列 clearQueue() { this.uploader.clearQueue(); this.progress = 0; this.currentFile = null; this.uploadedChunks = []; } } }; .upload-container { max-width: 800px; margin: 20px auto; padding: 20px; border: 1px solid #eee; border-radius: 8px; } .placeholder { min-height: 150px; border: 2px dashed #ccc; border-radius: 4px; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; } .tip { color: #666; font-size: 12px; margin-top: 10px; } .status-bar { margin-top: 15px; } .progress-wrap { margin-bottom: 15px; } .progress-bar { width: 100%; height: 20px; background: #f3f3f3; border-radius: 10px; overflow: hidden; margin: 5px 0; } .progress { height: 100%; background: #409eff; transition: width 0.3s; } .btn-group button { margin-right: 10px; padding: 5px 15px; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; } .btn-group button:disabled { background: #f5f5f5; color: #999; cursor: not-allowed; }

代码关键功能说明(小白必看)

  1. 兼容IE8:靠WebUploader的Flash模式(swf文件),记得把Uploader.swf放在public/static/webuploader/目录下(Vue3默认静态资源路径)。
  2. 断点续传
    • 文件加入队列时,用SparkMD5计算文件的MD5(唯一标识)。
    • 上传前调用queryUploadedChunks,从本地localStorage或后端接口查已上传的分片。
    • WebUploader会自动跳过已上传的分片,只传未传的部分。
  3. 文件夹上传
    • IE9+支持webkitdirectory属性(WebUploader自动处理),拖拽文件夹时会保留层级结构(比如/课程设计/文件管理系统)。
    • IE8不支持,只能手动让用户输入文件夹路径(比如在文件名前加课程设计/前缀),后端按路径创建文件夹。
  4. 加密传输
    • 前端用CryptoJS.AES.encrypt加密文件内容(示例里没写,可加在uploadBeforeSend事件里)。
    • 后端用相同的密钥解密(Python代码里实现)。

毕设演示注意事项(保命指南)

  1. 本地测试
    • 用Win7虚拟机装IE9,测试文件夹上传和断点续传(上传到50%时关闭浏览器,重新打开继续传)。
    • 用IE8虚拟机测试Flash上传(需允许浏览器运行Flash,学校机房可能需要调整安全设置)。
  2. 进度保存
    • 关闭浏览器再打开,刷新页面,看进度是否还在(依赖localStorage)。
  3. 大文件测试
    • 用10G的测试文件(网上找“10G测试文件生成器”),看分片上传是否正常,有没有内存溢出。

求救!后端Python怎么搞?

我现在后端Python还在啃,大概思路是:

  • 用Flask或Django写接口,接收分片(/api/upload/chunk)。
  • 把分片存到本地临时目录(比如F:/temp_uploads/)。
  • uploadedChunks表(或本地文件记录),合并分片成完整文件。
  • 加密存储(用AES解密前端传过来的内容,再存到项目目录)。

有没有Python大佬愿意带带弟弟?加群374992201,新人有红包!群里还有一起学后端的兄弟,平时布置作业互相监督,毕设答辩前互相调试代码~

(PS:老师说“能跑起来就行”,但我争取做到“看起来很牛”——毕竟这是大学最后作业了,冲就完事了!)

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

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

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

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

HTML5利用Vue.js实现信创环境下大文件分块上传?

要求&#xff1a;免费,开源,技术支持 技术&#xff1a;百度webuploader&#xff0c;分块&#xff0c;切片&#xff0c;断点续传&#xff0c;秒传&#xff0c;MD5验证&#xff0c;纯JS实现&#xff0c;支持第三方软件集成 前端&#xff1a;vue2,vue3,vue-cli,html5,webuploader …

作者头像 李华
网站建设 2026/3/13 18:53:25

PostgreSQL数据库

2.1 mvcc 原理 PostgreSQL 的 MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09; 是其实现高并发事务处理的核心机制。它通过维护数据的多个版本来避免读写冲突&#xff0c;同时支持不同的事务隔离级别。以下从底层实现到应用层逻辑的…

作者头像 李华
网站建设 2026/3/20 23:32:20

揭秘volatile关键字:让Java并发编程不再“卡壳”

文章目录为什么需要volatile&#xff1f;先看看并发编程的“坑”volatile的两大“超能力”1. 可见性保证2. 禁止指令重排序volatile的实现原理&#xff1a;底层探秘内存屏障&#xff1a;volatile的“守护神”硬件层面的支持&#xff1a;LOCK前缀指令volatile的局限性&#xff1…

作者头像 李华
网站建设 2026/3/20 23:32:18

海外仓退货怎么处理?海外仓退货费怎么计算?

做东南亚三方海外仓&#xff0c;退货业务就是块“烫手山芋”——处理不好&#xff0c;包裹堆积、账目混乱、客户流失全找上门&#xff1b;处理得当&#xff0c;反而能变成服务优势。今天就给各位同行拆解退货怎么高效处理&#xff0c;以及费用怎么算才不亏。一、海外仓退货的两…

作者头像 李华
网站建设 2026/3/20 22:10:55

nginx日志管理及日志格式定制

Nginx日志管理 一、日志管理概述 Nginx日志是服务器运行状态的核心记录&#xff0c;分为错误日志和访问日志两大类&#xff1a; 错误日志&#xff1a;记录服务器运行过程中的异常&#xff08;如文件不存在、权限错误、配置异常等&#xff09;&#xff0c;用于故障排查&#xff…

作者头像 李华
网站建设 2026/3/20 22:25:34

揭秘JUC:volatile与CAS,并发编程的两大基石

UC&#xff08;java.util.concurrent&#xff09;并发包&#xff0c;作为Java语言并发编程的利器&#xff0c;由并发编程领域的泰斗道格利&#xff08;Doug Lea&#xff09;精心打造。它提供了一系列高效、线程安全的工具类、接口及原子类&#xff0c;极大地简化了并发编程的开…

作者头像 李华