开发者日记大文件管理系统毕业设计攻坚实录日期2023年11月25日天气阴有小雨作为一名江苏高校的计算机专业大三学生我的毕业设计选题是全浏览器兼容的大文件管理系统需支持20GB文件传输、文件夹层级结构保留并覆盖IE8及国产信创浏览器龙芯/红莲花/奇安信。经过三周技术攻关现将关键实现方案与代码片段整理如下供同领域同学参考。一、技术架构设计1. 跨浏览器兼容方案浏览器类型前端方案后端适配IE8WebUploader Flash引擎禁用HTML5拖拽改用表单提交Chrome/FirefoxHTML5 File API WebUploader混合模式支持分片并发上传信创浏览器动态检测降级为单文件上传关闭WebSocket长连接2. 系统架构图客户端Vue3 → 分片上传 → PHP处理 → 阿里云OSS存储 ↓ MySQL记录元数据文件哈希/分片状态/用户权限二、核心代码实现1. 前端兼容性组件Vue3// src/components/SmartUploader.vueimport{onMounted,ref}fromvue;importWebUploaderfromwebuploader;import{detectBrowser}from/utils/browserDetect;exportdefault{setup(){constprogressref(0);constbrowserInfodetectBrowser();onMounted((){constconfig{swf:browserInfo.isIE8?/static/Uploader.swf:null,// IE8必需Flashserver:/api/upload,pick:#filePicker,accept:{title:All Files,extensions:*,mimeTypes:*},chunked:true,chunkSize:5*1024*1024,// 5MB分片threads:browserInfo.isLoongBrowser?1:3,// 龙芯浏览器单线程formData:{browserType:browserInfo.type,timestamp:Date.now()}};// 国产浏览器特殊处理if(browserInfo.isRedLotus){config.dndfalse;// 禁用拖拽上传config.disableGlobalDndtrue;}constuploaderWebUploader.create(config);// 文件夹上传处理非IE8if(!browserInfo.isIE8WebUploader.Browser.HTML5){uploader.on(filesQueued,(files){files.forEach(file{if(file.relativePath){// HTML5文件夹结构traverseFolder(file,uploader);}else{uploader.upload(file);}});});}// 进度监控uploader.on(uploadProgress,(file,percentage){progress.valueMath.round(percentage*100);});});// 递归解析文件夹HTML5 APIconsttraverseFolder(entry,uploader){constdirReaderentry.createReader();dirReader.readEntries(entries{entries.forEach(subEntry{if(subEntry.isFile){subEntry.file(file{file.relativePath${entry.relativePath}/${file.name};uploader.addFiles(file);});}else{subEntry.relativePath${entry.relativePath}/${subEntry.name};traverseFolder(subEntry,uploader);}});});};return{progress};}};2. 后端分片处理PHP// api/upload_handler.php[accessKeyIdyour-aliyun-key,accessKeySecretyour-aliyun-secret,endpointoss-cn-shanghai.aliyuncs.com,bucketyour-bucket],mysql[hostlocalhost,dbnamefile_manager,userroot,passpassword]];// 处理分片上传try{$pdonewPDO(mysql:host{$config[mysql][host]};dbname{$config[mysql][dbname]},$config[mysql][user],$config[mysql][pass]);$chunkIndex$_POST[chunk]??0;$totalChunks$_POST[chunks]??1;$fileMd5$_POST[md5]??md5_file($_FILES[file][tmp_name]);// 兼容IE8$relativePath$_POST[relativePath]??;$userId$_SESSION[user_id]??0;// 存储临时分片$chunkDir/tmp/chunks/{$fileMd5};if(!is_dir($chunkDir))mkdir($chunkDir,0777,true);move_uploaded_file($_FILES[file][tmp_name],{$chunkDir}/{$chunkIndex});// 记录分片状态$stmt$pdo-prepare(REPLACE INTO file_chunks (md5, chunk_index, total_chunks, user_id, created_at) VALUES (?, ?, ?, ?, NOW()));$stmt-execute([$fileMd5,$chunkIndex,$totalChunks,$userId]);// 合并分片最后一个分片if($chunkIndex$totalChunks-1){$ossPathuploads/{$userId}/.ltrim($relativePath,/);mergeChunks($fileMd5,$totalChunks,$ossPath,$config);// 记录完整文件信息$fileStmt$pdo-prepare(INSERT INTO files (name, path, md5, size, user_id, created_at) VALUES (?, ?, ?, ?, ?, NOW()));$fileStmt-execute([basename($relativePath),$ossPath,$fileMd5,$_POST[size]??filesize($_FILES[file][tmp_name]),$userId]);echojson_encode([statuscompleted,path$ossPath]);}else{echojson_encode([statuspending]);}}catch(Exception$e){http_response_code(500);echojson_encode([error$e-getMessage()]);}// 分片合并函数functionmergeChunks($md5,$chunks,$ossPath,$config){$tempFile/tmp/{$md5}_merged;$ossClientnewOssClient($config[oss][accessKeyId],$config[oss][accessKeySecret],$config[oss][endpoint]);// 合并本地文件for($i0;$i$chunks;$i){file_put_contents($tempFile,file_get_contents(/tmp/chunks/{$md5}/{$i}),FILE_APPEND);}// 上传至OSS$ossClient-uploadFile($config[oss][bucket],$ossPath,$tempFile);// 清理临时文件unlink($tempFile);for($i0;$i$chunks;$i){unlink(/tmp/chunks/{$md5}/{$i});}rmdir(/tmp/chunks/{$md5});}3. 数据库表设计-- 文件分片状态表CREATETABLEfile_chunks(idBIGINTAUTO_INCREMENTPRIMARYKEY,md5VARCHAR(32)NOTNULLCOMMENT文件唯一标识,chunk_indexINTNOTNULLCOMMENT分片序号,total_chunksINTNOTNULLCOMMENT总分片数,user_idINTNOTNULLCOMMENT关联用户,created_atDATETIMENOTNULLCOMMENT记录时间,UNIQUEKEYmd5_chunk(md5,chunk_index))ENGINEInnoDBDEFAULTCHARSETutf8mb4;-- 文件元数据表CREATETABLEfiles(idBIGINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(512)NOTNULLCOMMENT文件名含扩展名,pathVARCHAR(1024)NOTNULLCOMMENTOSS存储路径,md5VARCHAR(32)NOTNULLCOMMENT文件哈希值,sizeBIGINTNOTNULLCOMMENT文件大小字节,user_idINTNOTNULLCOMMENT上传用户ID,created_atDATETIMENOTNULLCOMMENT上传时间,INDEXidx_user_md5(user_id,md5))ENGINEInnoDBDEFAULTCHARSETutf8mb4;三、关键问题解决方案IE8文件夹上传方案通过的降级处理代码// 兼容IE8的文件夹选择if(browserInfo.isIE8){document.getElementById(legacyFolderInput).onclick(){document.getElementById(legacyInput).click();};document.getElementById(legacyInput).onchange(e){constfilese.target.files;// 模拟文件夹结构需后端配合解析路径};}龙芯浏览器性能优化发现龙芯CPU在多线程分片时CPU占用率达100%解决强制单线程上传threads: 120GB文件内存控制前端使用FileReader.readAsArrayBuffer分块读取后端PHP配置memory_limit -1由分片逻辑接管内存四、毕业设计创新点智能降级机制通过User-Agent自动切换上传策略// 浏览器检测示例exportfunctiondetectBrowser(){constuanavigator.userAgent;return{isIE8:ua.includes(MSIE 8.0),isLoongBrowser:ua.includes(LoongBrowser),isRedLotus:ua.includes(RedLotus),type:ua.includes(Edge)?edge:ua.includes(Firefox)?firefox:unknown};}信创浏览器安全加固禁用WebUploader的Flash引擎部分信创浏览器Flash存在漏洞强制HTTPS传输分片数据可视化上传监控基于ECharts实现实时速度/剩余时间预测求助信息目前奇安信浏览器在合并分片时出现路径截断问题欢迎加入QQ群374992201共同调试今日进展完成基础分片上传功能明日将实现断点续传逻辑。签名江苏某高校 · 计算机1903班 · 李想2023年11月25日 夜项目资源GitHub仓库待开源https://github.com/jsu-graduation/file-manager测试环境访问http://test.yourdomain.com:8080/uploader文档中心/docs/目录下的《全浏览器兼容方案.pdf》致谢感谢群内陈工提供的龙芯浏览器测试机以及赵学长分享的阿里云OSS性能优化方案安装环境PHP:7.2.14调整块大小NOSQLNOSQL不需要任何配置可以直接访问测试SQL创建数据库您可以直接复制脚本进行创建配置数据库连接安装依赖访问页面进行测试数据表中的数据效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。免费下载示例点击下载完整示例