网站构建计划,wordpress页面样式,电子科技网站模板,赣州有没有做网站的前端程序员外包项目解决方案#xff1a;原生JS大文件传输系统#xff08;Vue3实现#xff09;
兄弟#xff0c;作为陕西的个人前端程序员#xff0c;我太懂你现在的处境了——甲方要大文件上传#xff0c;还要兼容IE9#xff0c;预算卡得死死的#xff0c;自己头发都快…前端程序员外包项目解决方案原生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. 核心组件大文件上传兼容IE9import { 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创建安装依赖npminstallvue3 crypto-js element-plus后端SpringBoot项目需提供分片上传、合并、文件列表接口。存储阿里云OSS配置跨域CORS允许前端域名访问。2. 关键配置AES密钥从后端动态获取示例中为固定值实际需调用后端接口/api/config/aes-key。OSS直传链接后端需返回OSS的oss://bucket/path/file格式链接或签名后的HTTP链接。断点续传存储使用localStorageIE9支持生产环境建议替换为IndexedDB容量更大。3. 兼容性处理IE9不支持webkitDirectory用传统选择文件手动拼接伪路径如/fileId/filename。使用FileReader读取文件内容示例已兼容。现代浏览器直接使用webkitDirectory获取文件夹递归遍历webkitRelativePath。4. 注意事项分片大小5MB为兼容IE9的最优值过小会增加请求次数过大可能导致内存溢出。加密传输前端加密仅保护传输过程后端需用SM4解密后存储密钥需安全传输。大文件测试建议在开发环境用20G测试文件验证断点续传可用水印工具生成大文件。四、技术支持与社群1. 7×24小时支持加群QQ374992201我“紧急求助”我会远程帮你调试用TeamViewer连你的电脑。遇到“上传卡住”“IE9白屏”等问题直接甩日志截图我帮你分析。2. 群内资源开源代码库群文件共享《大文件传输前端完整源码》含Vue3组件、加密工具类。接单互助群里每天更新外包需求企业官网/政务系统200程序员在线接单。推荐提成推荐新客户得20%提成项目2万提4千10个项目就是4万比打工香多了兄弟这套前端代码是我接外包时用过的“压箱底”方案已经帮3个客户上线甲方反馈“比预期还稳”。代码开箱即用100元预算内搞定所有需求。现在加群还能领新人红包1~99元推荐客户赚提成这波血赚附完整开发文档含OSS对接、密钥管理、IE9调试已上传群文件输入密码abc123即可下载将组件复制到项目中示例中已经包含此目录引入组件配置接口地址接口地址分别对应文件初始化文件数据上传文件进度文件上传完毕文件删除文件夹初始化文件夹删除文件列表参考http://www.ncmem.com/doc/view.aspx?ide1f49f3e1d4742e19135e00bd41fa3de处理事件启动测试启动成功效果数据库效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。批量下载支持文件批量下载下载续传文件下载支持离线保存进度信息刷新页面关闭页面重启系统均不会丢失进度信息。文件夹下载支持下载文件夹并保留层级结构不打包不占用服务器资源。下载示例点击下载完整示例