如何通过AJAX和Multer获取上传文件名并实现文件重名校验
问题根因
你当前的代码存在两个核心逻辑问题:
- 文件存在性校验逻辑放在multer执行之前,此时请求还没有被multer解析,无法获取上传文件的文件名,自然不能做针对性校验
- 全局变量
uploadedFileName在并发请求场景下会被不同请求覆盖,会出现逻辑混乱,不能用于生产环境
正确实现方案
直接将文件存在性校验逻辑放在multer的filename回调中执行,这个阶段已经可以拿到上传文件的原始名称,同时可以通过回调传递错误终止上传流程。
修改后的完整后端代码如下:
var multer = require('multer'); var fs = require('fs'); var path = require('path'); // 统一配置上传目录,避免重复拼接路径 const UPLOAD_DIR = path.join(__dirname, './client/uploads/'); // 服务启动时提前创建上传目录,不需要每次请求都校验 if (!fs.existsSync(UPLOAD_DIR)) { fs.mkdirSync(UPLOAD_DIR, { recursive: true }); } var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, UPLOAD_DIR); }, filename: function (req, file, cb) { const fileName = file.originalname; const targetFilePath = path.join(UPLOAD_DIR, fileName); // 校验同名文件是否存在 if (fs.existsSync(targetFilePath)) { const existErr = new Error('同名文件已存在,上传终止'); existErr.code = 'FILE_DUPLICATE'; return cb(existErr); } // 文件不存在则继续保存 cb(null, fileName); } }); // 全局初始化multer实例,不要每次请求都重复创建 const uploadHandler = multer({ storage: storage }).array('file', 12); router.upload = function (req, res, cb) { uploadHandler(req, res, function (err) { if (err) { // 区分错误类型返回对应提示 if (err.code === 'FILE_DUPLICATE') { return res.status(400).json({ success: false, msg: err.message }); } return res.status(500).json({ success: false, msg: '上传失败', error: err.message }); } // 直接从req.files获取上传文件信息,不要使用全局变量 const uploadNames = req.files.map(item => item.originalname); return res.json({ success: true, files: uploadNames }); }); };
附加优化建议
- 你当前前端代码中
fd.append('file', file, "filename.dat")的第三个参数会强制将所有上传文件命名为filename.dat,如果需要保留文件原始名称,删除第三个参数即可 - 可在multer配置中新增
limits、fileFilter参数限制上传文件的大小、类型,提升接口安全性 - 高并发场景下如果存在相同文件同时上传的场景,可给文件名加短随机后缀、或者用文件内容哈希校验避免冲突
内容的提问来源于stack exchange,提问作者rmarques
相关产品推荐
相关产品推荐

