使用Multer上传视频至Cloudinary时req.file.path未定义求助
问题
尝试通过Multer将视频文件上传至Cloudinary多日,图片上传正常,但上传视频时触发错误:
Cannot read property 'path' of undefined
从前端到redux-slice、redux-service全程打印FormData,所有环节中“src”字段均为文件;HTTP请求头也确认存在;Node端打印req.body已获取到数据:
{ src: 'Pexels Videos 2098989.mp4', ressort: 'Freizeit', theme: 'Lorem Iosum', title: 'Lorem ipsum dolor sit amet, consectetur adipisicing' }
(node:4260) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'path' of undefined
尝试过const {req.body.src} = req.file这类写法无效,移除调试代码后req.file.path仍未定义。
原因分析
- HTTP请求头错误:前端axios请求手动设置了
Content-Type: application/json,但FormData上传文件需要浏览器自动生成multipart/form-data头,手动设置会破坏文件解析。 - Multer配置笔误:diskStorage中的文件名处理函数写成了
fileName(正确应为filename),导致Multer无法正确生成文件路径,req.file无法被赋值。 - 文件类型校验错误:mimetype判断中存在错误值(如
video/mp3应为audio/mpeg,错误提示中的.m4应为.mp4),可能导致部分文件被过滤。
解决方案
1. 修正axios请求的Content-Type
删除手动设置的Content-Type,让axios自动根据FormData生成正确的请求头:
const createVideos = async (videosData, token)=>{ if(videosData){ for(let value of videosData){ console.log(value); } } const config = { headers:{ token: `Bearer ${token}` } } const response = await axios.post(API_URL, videosData, config); console.log(response.data); return response.data; }
2. 修复Multer的diskStorage配置
将fileName改为正确的filename,同时移除无效的console.log(req.file)(此时req.file还未生成,打印无意义):
const storage = multer.diskStorage({ destination:(req,file, callback)=>{ callback(null, path.resolve(process.cwd(), 'frontside/public/uploads')); }, filename: (req, file, callback)=>{ callback(null, Date.now()+ "--"+ path.extname(file.originalname)); }, })
3. 修正文件类型校验逻辑
修正mimetype的错误值,同时优化错误提示:
fileFilter:(req,file,callback)=>{ const allowedTypes = [ "image/png", "image/jpg", "image/jpeg", "audio/mpeg", // 对应mp3格式 "video/mp4" ]; if(allowedTypes.includes(file.mimetype)){ callback(null, true); } else{ callback(new Error("仅支持 .png, .jpg, .jpeg, .mp3, .mp4 格式")); } },
4. 后端增加req.file存在性校验
避免因文件上传失败导致的崩溃:
router.post("/", uploadVideo, verifyTokenAndAuthorization, async (req,res)=>{ try{ if(!req.file) { return res.status(400).json({message: "未上传有效文件"}); } const result = await cloudinary.uploader.upload(req.file.path, { upload_preset: "Mern_redux-practice", resource_type: "video", }); const newVideos= new Videos({ cloudinary_id: result.public_id, ressort: req.body.ressort, theme: req.body.theme, title:req.body.title, src: result.secure_url, }) const savedVideos= await newVideos.save(); res.status(200).json(savedVideos); } catch(error){ res.status(500).json({message: "操作失败", error: error.message}); console.log(error); } });
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

