如何在Node.js Express应用中基于Multer实现文件上传至指定文件夹及相关功能开发?
如何在Node.js Express应用中基于Multer实现文件上传至指定文件夹及相关功能开发?
我来一步步带你搞定这些文件上传相关的功能,从基础配置到复用工具都给你安排得明明白白:
核心功能清单
- 配置Multer
- 将Multer设置为全局中间件
- 编写可复用工具函数获取上传文件/多文件路径
- 将上传文件转移到专用文件夹
- 实现单文件上传并转移到专用文件夹
- 实现多文件上传并转移到专用文件夹
- 编写可复用的文件删除工具函数
- 删除单个文件
- 删除多个文件
具体实现代码及说明
首先引入所需的依赖包:
import multer from 'multer' import path from 'path' import fs from 'fs'
1. 配置Multer存储引擎
先配置Multer的磁盘存储规则,确保文件能存到指定的专用文件夹,还能自动创建不存在的目录:
const storage = multer.diskStorage({ destination: (req, file, cb) => { // 定义文件存储的目标目录 const uploadDir = path.join(__dirname, "../../public/files/"); // 如果目录不存在则递归创建 if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }); } cb(null, "public/files"); }, filename: (req, file, cb) => { // 生成唯一文件名,避免重名覆盖 const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); cb(null, uniqueSuffix + '-' + file.originalname); } }); // 初始化Multer实例 const upload = multer({ storage: storage });
2. 设置为全局中间件(可选)
如果你的Express应用需要全局启用文件上传功能,可以把Multer挂载为全局中间件:
// 这里以单文件上传为例,可根据需求调整为array/fields等 app.use(upload.single('file'));
不过更推荐根据不同路由的需求单独使用中间件,这样灵活性更高。
3. 可复用工具:获取上传文件路径
写两个小工具函数,方便快速拿到单个或多个上传文件的路径:
// 获取单个上传文件的完整路径 const getSingleFilePath = (req) => { if (!req.file) return null; return path.join(req.file.destination, req.file.filename); }; // 获取多个上传文件的路径数组 const getMultipleFilePaths = (req) => { if (!req.files || req.files.length === 0) return []; return req.files.map(file => path.join(file.destination, file.filename)); };
4. 单文件上传接口示例
创建一个路由处理单文件上传,文件会自动存到我们指定的文件夹:
// 单文件上传路由 app.post('/upload/single', upload.single('file'), (req, res) => { try { const filePath = getSingleFilePath(req); res.status(200).json({ success: true, message: '文件上传成功', filePath: filePath }); } catch (error) { res.status(500).json({ success: false, message: '文件上传失败', error: error.message }); } });
5. 多文件上传接口示例
同样,写一个处理多文件上传的路由,这里限制最多上传5个文件,可按需调整:
// 多文件上传路由 app.post('/upload/multiple', upload.array('files', 5), (req, res) => { try { const filePaths = getMultipleFilePaths(req); res.status(200).json({ success: true, message: '多文件上传成功', filePaths: filePaths }); } catch (error) { res.status(500).json({ success: false, message: '多文件上传失败', error: error.message }); } });
6. 可复用工具:删除文件
写通用的删除函数,支持单个和多个文件删除:
// 删除单个文件 const deleteSingleFile = (filePath) => { try { if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); return { success: true, message: '文件删除成功' }; } return { success: false, message: '文件不存在' }; } catch (error) { return { success: false, message: '文件删除失败', error: error.message }; } }; // 删除多个文件 const deleteMultipleFiles = (filePaths) => { const results = []; filePaths.forEach(filePath => { results.push(deleteSingleFile(filePath)); }); return results; };
7. 文件删除接口示例
创建路由调用删除工具函数:
// 删除单个文件路由 app.delete('/file/delete', (req, res) => { const { filePath } = req.body; const result = deleteSingleFile(filePath); res.status(result.success ? 200 : 404).json(result); }); // 删除多个文件路由 app.delete('/files/delete', (req, res) => { const { filePaths } = req.body; const results = deleteMultipleFiles(filePaths); res.status(200).json(results); });
备注:内容来源于stack exchange,提问作者Soumik Ahammed




