You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node.js Multer实现文件夹上传?配合react-dropzone的方案

实现可行性结论

完全可以实现该需求。整体实现逻辑是前端通过react-dropzone获取文件夹内所有文件的完整相对路径,随文件一同传到后端;后端用Multer接收文件后,按照相对路径创建对应目录层级存储文件,就能完整还原原文件夹结构,不需要提前打包zip。


前端实现(基于react-dropzone)
  • 首先安装依赖:npm install react-dropzone
  • 配置dropzone开启文件夹选择能力,通过浏览器原生webkitRelativePath属性获取每个文件在原文件夹中的相对路径,用FormData提交到后端:
import { useDropzone } from 'react-dropzone';

function FolderUploader() {
  const { getRootProps, getInputProps } = useDropzone({
    // 开启文件夹选择模式
    webkitdirectory: true,
    directory: true,
    onDrop: (acceptedFiles) => {
      const formData = new FormData();
      // 遍历文件夹下所有文件加入FormData
      acceptedFiles.forEach(file => {
        // 第三个参数传入文件的相对路径,后端可直接读取
        formData.append('folderFiles', file, file.webkitRelativePath);
      });
      // 发送上传请求
      fetch('/api/upload-folder', {
        method: 'POST',
        body: formData
      }).then(res => res.json()).then(data => {
        console.log('上传完成', data);
      });
    }
  });

  return (
    <div {...getRootProps({style: {border: '2px dashed #ccc', padding: '20px'}})}>
      <input {...getInputProps()} />
      <p>拖拽文件夹到此处上传,或点击选择文件夹</p>
    </div>
  );
}

export default FolderUploader;

后端实现(基于Multer)
  • 先安装依赖:npm install express multer fs-extra,fs-extra用于简化多级目录创建逻辑
  • 配置Multer存储规则,自动根据文件相对路径创建目录存储:
const express = require('express');
const multer = require('multer');
const fs = require('fs-extra');
const path = require('path');
const app = express();

// 配置Multer磁盘存储规则
const storage = multer.diskStorage({
  destination: async (req, file, cb) => {
    // 拆分相对路径中的目录部分
    const relativeDir = path.dirname(file.originalname);
    // 拼接本地存储的完整目录,默认存在项目根目录的uploads文件夹下
    const uploadDir = path.join(__dirname, 'uploads', relativeDir);
    // 递归创建目录,不存在则自动新建
    await fs.mkdirs(uploadDir);
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    // 取原文件名作为存储文件名
    const fileName = path.basename(file.originalname);
    cb(null, fileName);
  }
});

// 初始化Multer实例,可根据业务调整大小、数量限制
const upload = multer({
  storage: storage,
  limits: {
    fileSize: 1024 * 1024 * 100, // 单文件最大100M
    files: 1000 // 单次最多上传1000个文件
  }
});

// 上传接口,字段名需和前端FormData.append的第一个参数保持一致
app.post('/api/upload-folder', upload.array('folderFiles', 1000), (req, res) => {
  res.json({
    code: 200,
    message: '文件夹上传成功',
    files: req.files
  });
});

app.listen(3001, () => {
  console.log('服务运行在3001端口');
});

注意事项
  • 浏览器兼容性:webkitRelativePath属性支持所有主流现代浏览器(Chrome、Edge、Firefox),IE浏览器不支持,如有兼容需求需额外做降级处理
  • 路径安全:可增加路径校验逻辑,拦截包含../的恶意路径,避免文件被存储到非预期目录
  • 大文件夹优化:如果需要上传超大文件夹,可额外增加分片上传、断点续传逻辑,普通场景上述实现可直接使用

内容的提问来源于stack exchange,提问作者Avinash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 06:45:04