开发者日记:WebUploader大文件传输系统开发实录
日期:2023年11月15日
天气:晴

作为浙江的一名独立开发者,近期接到一个企业级需求:开发一套支持20GB大文件传输的系统,需兼容全平台(Windows/macOS/Linux)和全浏览器(含IE8),并实现文件夹层级结构保留的上传下载功能。经过一周的调研与实战,现将关键技术方案和代码片段整理如下,供同行参考。


一、技术选型与架构设计

  1. 前端框架

    • Vue3 CLI + WebUploader(百度开源组件)
    • 兼容性处理:通过@babel/polyfillwebuploader.flashonly.js支持IE8
    • 文件夹上传:利用WebUploader的directory属性结合HTML5 File System API
  2. 后端架构

    • PHP 8.1 + Swoole(异步IO处理大文件)
    • 分片上传:基于WebUploader的chunked模式,每片5MB
    • 秒传实现:通过MD5校验文件唯一性
  3. 存储方案

    • 阿里云OSS/华为云OBS双活架构
    • 本地MySQL记录元数据(文件路径、分片信息、MD5等)

二、核心代码实现

1. 前端配置(Vue3组件)
// src/components/Uploader.vue
import WebUploader from 'webuploader';
import 'webuploader/dist/webuploader.css';

export default {
  mounted() {
    const uploader = WebUploader.create({
      swf: '/static/Uploader.swf', // IE8兼容
      server: '/api/upload',
      pick: '#picker',
      accept: {
        title: 'All',
        extensions: '*',
        mimeTypes: '*'
      },
      compress: false,
      chunked: true,
      chunkSize: 5 * 1024 * 1024, // 5MB分片
      threads: 4, // 并发数
      formData: {
        dir: '/uploads' // 默认存储路径
      },
      // 文件夹上传关键配置
      directory: true,
      disableGlobalDnd: true
    });

    // 监听文件添加(包含文件夹)
    uploader.on('filesQueued', (files) => {
      files.forEach(file => {
        if (file.relativePath) { // 文件夹层级处理
          console.log('Folder path:', file.relativePath);
        }
      });
      uploader.upload();
    });

    // 进度监控
    uploader.on('uploadProgress', (file, percentage) => {
      console.log(`${file.name} 上传进度: ${Math.round(percentage * 100)}%`);
    });
  }
};
2. 后端处理(PHP + Swoole)
// api/upload.php
prepare("INSERT INTO chunks (md5, chunk_index, path) VALUES (?, ?, ?)");
    $stmt->execute([$md5, $chunk, $tmpFile]);

    // 所有分片上传完成后合并
    if ($chunk === $chunks - 1) {
        $finalPath = "/uploads/{$relativePath}" . basename($_POST['name']);
        $mergedFile = "/tmp/{$md5}_merged";

        // 合并分片(需根据实际存储方案调整)
        for ($i = 0; $i < $chunks; $i++) {
            file_put_contents($mergedFile, file_get_contents("/tmp/{$md5}_{$i}"), FILE_APPEND);
        }

        // 上传至阿里云
        $ossClient->putObject('your-bucket', $finalPath, fopen($mergedFile, 'rb'));

        // 清理临时文件
        unlink($mergedFile);
        for ($i = 0; $i < $chunks; $i++) unlink("/tmp/{$md5}_{$i}");

        echo json_encode(['status' => 'success', 'path' => $finalPath]);
    }
}
3. MySQL表设计
CREATE TABLE `chunks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `md5` varchar(32) NOT NULL COMMENT '文件唯一标识',
  `chunk_index` int(11) NOT NULL COMMENT '分片索引',
  `path` varchar(512) NOT NULL COMMENT '分片存储路径',
  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `md5_chunk` (`md5`, `chunk_index`)
) ENGINE=InnoDB;

三、关键问题解决

  1. IE8兼容性

    • 必须引入Flash版本的WebUploader(webuploader.flashonly.js
    • 禁用HTML5的FormData,改用隐藏iframe提交
  2. 文件夹层级保留

    • 前端通过file.relativePath获取完整路径
    • 后端需解析路径并递归创建云存储目录(如阿里云的putObject需指定完整路径)
  3. 大文件断点续传

    • 前端记录已上传分片索引
    • 后端MySQL查询缺失分片,返回skip_upload: true

四、后续优化计划

  1. 增加WebSocket实时进度推送
  2. 实现多云存储负载均衡
  3. 开发管理后台(基于Vue3 + Element Plus)

寻求帮助:目前文件夹上传在Safari浏览器存在路径解析异常,欢迎大神加入QQ群 374992201 指导调试!

今日进度:完成基础分片上传功能,明日将攻克文件夹跨浏览器兼容性问题。


(签名)
浙江独立开发者 · 林默
2023年11月15日 夜


附:完整项目地址
GitHub(待开源):https://github.com/your-repo/webuploader-pro
技术文档:项目根目录/docs/文件夹内

安装环境

PHP:7.2.14
Alt

调整块大小

Alt

NOSQL

NOSQL不需要任何配置,可以直接访问测试
Alt

SQL

创建数据库

您可以直接复制脚本进行创建
Alt
Alt

配置数据库连接

Alt

安装依赖

Alt

访问页面进行测试

Alt

数据表中的数据

Alt

效果预览

文件上传

文件上传

文件刷新续传

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

文件夹上传

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

免费下载示例

点击下载完整示例

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐