毕业设计开发日记 – 大文件管理系统(WebUploader+Vue3+PHP) 日期:2023年X月X日 天气:晴
一、项目背景与需求确认
作为武汉某高校软件工程专业大三学生,我的毕业设计选题为**“基于云存储的跨浏览器大文件管理系统”**,核心需求包括:
- 前端:Vue3 + WebUploader(兼容层)
- 后端:PHP(Zend Framework) + MySQL(元数据) + 阿里云OSS(存储)
- 工具:Zend Studio + Vue CLI
二、技术选型与兼容性方案
1. 上传组件选择
- WebUploader:支持Flash回退,兼容IE8+,但需处理国产浏览器Flash策略问题;
- H5 File API:现代浏览器原生支持,但IE8/9需Polyfill(如FileAPI库)。
最终方案:
- 主方案:WebUploader(Flash+H5混合模式)
- 降级方案:IE8/9使用FileAPI.js模拟分块上传
2. 文件夹上传实现
- 前端:通过webkitdirectory(Chrome/Firefox)和directory(Edge)属性递归读取文件夹结构,生成JSON元数据(如{path: "a/b/c.txt", size: 1024});
- 后端:解析元数据,在OSS中按路径创建虚拟目录结构。
关键代码(Vue3组件):
// src/components/Uploader.vue
import { onMounted } from 'vue';
import WebUploader from 'webuploader';
import 'webuploader/dist/webuploader.css';
let uploader;
onMounted(() => {
// 初始化WebUploader(兼容模式)
uploader = WebUploader.create({
swf: '/path/to/Uploader.swf', // Flash回退
server: '/api/upload/chunk',
chunked: true,
chunkSize: 5 * 1024 * 1024, // 5MB分块
threads: 3,
formData: { token: '用户鉴权token' },
compress: false
});
// 绑定文件夹选择事件(现代浏览器)
document.getElementById('filePicker').addEventListener('change', (e) => {
const files = e.target.files;
const folderMeta = [];
Array.from(files).forEach(file => {
const pathParts = file.webkitRelativePath.split('/');
folderMeta.push({
path: file.webkitRelativePath,
size: file.size,
lastModified: file.lastModified
});
});
// 发送元数据到后端预创建目录
fetch('/api/upload/init', {
method: 'POST',
body: JSON.stringify({ files: folderMeta })
});
});
});
三、后端PHP实现(Zend Framework)
1. 分块上传接口
// application/controllers/UploadController.php
class UploadController extends Zend_Controller_Action {
public function chunkAction() {
$fileId = $_POST['fileId'];
$chunkIndex = $_POST['chunkIndex'];
$totalChunks = $_POST['totalChunks'];
$tempPath = "/tmp/{$fileId}_chunk_{$chunkIndex}";
// 保存分块到临时目录
move_uploaded_file($_FILES['file']['tmp_name'], $tempPath);
// 所有分块上传完成后合并
if ($chunkIndex === $totalChunks – 1) {
$this->_mergeChunks($fileId);
$this->_uploadToOSS($fileId); // 调用阿里云OSS SDK
unlink("/tmp/{$fileId}_meta.json"); // 清理临时文件
}
echo json_encode(['status' => 'success']);
}
private function _mergeChunks($fileId) {
$meta = json_decode(file_get_contents("/tmp/{$fileId}_meta.json"), true);
$outputPath = "/tmp/{$meta['filename']}";
for ($i = 0; $i < $meta['totalChunks']; $i++) {
$chunkPath = "/tmp/{$fileId}_chunk_{$i}";
file_put_contents($outputPath, file_get_contents($chunkPath), FILE_APPEND);
unlink($chunkPath);
}
}
}
2. 文件夹结构预创建
public function initAction() {
$folderMeta = json_decode($this->getRequest()->getRawBody(), true);
$ossClient = new AliyunOSSClient(/* 配置 */);
foreach ($folderMeta['files'] as $file) {
$pathParts = explode('/', $file['path']);
array_pop($pathParts); // 移除文件名,保留目录
$dirPath = implode('/', $pathParts);
if (!empty($dirPath)) {
$ossClient->createObjectDir('your-bucket', $dirPath);
}
}
// 保存文件元数据到MySQL
$this->_saveToDatabase($folderMeta);
}
四、兼容性优化与测试
IE8/9适配:
- 引入es5-shim和json2.js;
- 使用XDomainRequest替代XMLHttpRequest处理跨域。
国产浏览器测试:
- 龙芯浏览器(MIPS架构):需验证Flash插件可用性;
- 奇安信浏览器:启用兼容模式强制使用IE内核。
断点续传逻辑:
- 前端记录已上传分块索引(localStorage);
- 后端通过ETag校验分块完整性。
五、当前问题与求助
文件夹上传元数据传递:
- 如何高效地将数千个文件的路径结构传输到后端?
- 考虑压缩为ZIP后解析,但会增加复杂度。
加密传输方案:
- 是否需要在前端对分块进行AES加密?
- 推荐使用crypto-js库,但需评估性能影响。
寻求帮助:
- 加入QQ群 374992201 获取完整代码和调试支持;
- 欢迎大神提供文件夹元数据优化方案或加密传输实现示例。
明日计划:
- 完成MySQL表结构设计(文件元数据、分块记录);
- 搭建本地测试环境(XAMPP + Zend Server)。
签名: —— 一名在毕业设计深渊中挣扎但永不放弃的武汉程序猿 🚀
安装环境
PHP:7.2.14 
调整块大小

NOSQL
NOSQL不需要任何配置,可以直接访问测试 
SQL
创建数据库
您可以直接复制脚本进行创建

配置数据库连接

安装依赖

访问页面进行测试

数据表中的数据

效果预览
文件上传

文件刷新续传
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传 
文件夹上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。 
免费下载示例
点击下载完整示例



