如何通过Node.js后端上传文件到MySQL数据库并展示照片,解决undefined问题
问题原因
- 提交数据格式不匹配:前端通过axios直接提交JSON格式数据,未使用
multipart/form-data格式,multer仅能解析multipart/form-data类型的请求,无法识别JSON内的文件字段。 - 文件对象存储错误:文件输入框的
onChange回调中仅存储了e.target.value(浏览器返回的虚拟路径字符串),未存储真实的File对象,后端无法获取文件内容。 - 表单提交逻辑问题:表单提交未阻止默认刷新行为,且axios提交未使用构造好的FormData实例,表单上写的
enctype="multipart/form-data"不会自动生效。 - 多文件字段处理不匹配:存在
Photo和UserFP两个文件字段,后端仅配置了upload.single("Photo")处理单个文件,若需要同时上传两个文件需调整multer配置。
修正方案
前端代码修改
- 修改文件输入框的onChange逻辑,存储真实File对象,移除文件输入的value属性(受控文件输入不需要绑定value)
- 提交时构造FormData对象,所有字段都添加到FormData中
- 阻止表单默认提交行为,axios请求头指定正确的格式
关键修改代码:
文件输入部分:
<div className="form-group"> <label>UserFP</label> <input type="file" className="form-control" placeholder="UserFP" onChange={(e) => { setUserFP(e.target.files[0]); // 存储File对象 }} name="UserFP" /> </div> <div className="form-group"> <label>Photo</label> <input type="file" className="form-control" placeholder="Photo" onChange={(e) => { setPhoto(e.target.files[0]); // 存储File对象 }} name="Photo" /> </div>
表单提交和editData方法部分:
<form onSubmit={(e) => { e.preventDefault(); editData(); }}>
const editData = async () => { // 构造FormData const formData = new FormData(); formData.append('CmpnyCode', CmpnyCode); formData.append('UserID', UserID); formData.append('UserFullName', UserFullName); formData.append('UserDetail', UserDetail); formData.append('LoginID', LoginID); formData.append('Password', Password); formData.append('UserPin', UserPin); formData.append('UserEmailID', UserEmailID); // 文件字段判断:编辑场景下未重新上传文件则传原有旧值 if (UserFP instanceof File) { formData.append('UserFP', UserFP); } else { formData.append('UserFP', UserFP || ''); } if (Photo instanceof File) { formData.append('Photo', Photo); } else { formData.append('Photo', Photo || ''); } formData.append('IsActive', IsActive); formData.append('LicCount', LicCount); formData.append('DateCreated', DateCreated); formData.append('CreatedBy', CreatedBy); formData.append('RecordChanged', RecordChanged); formData.append('LocationID', LocationID); formData.append('isValid', isValid); formData.append('isDeleted', isDeleted); await axios.put("http://localhost:8000/upusermst/" + argu, formData, { headers: { 'Content-Type': 'multipart/form-data' } }); history.push("/usermst"); };
后端代码修改
如果需要同时接收两个文件,调整multer配置为fields模式,从req.files获取文件对象;如果仅需接收Photo字段的单个文件,保持upload.single("Photo")即可,从req.file获取:
// 方式1:同时接收两个文件字段 app.put("/upusermst/:UserID", upload.fields([{name: 'Photo'}, {name: 'UserFP'}]), (req, res) => { const userid = req.params.UserID; const CompanyCode = req.body.CmpnyCode; const UserID = req.body.UserID; const UserFullName = req.body.UserFullName; const UserDetail = req.body.UserDetail; const LoginID = req.body.LoginID; const Password = req.body.Password; const UserPin = req.body.UserPin; const UserEmailID = req.body.UserEmailID; // 有新上传文件就取二进制,没有就用前端传的旧值 const UserFP = req.files?.UserFP ? req.files.UserFP[0].buffer : req.body.UserFP; const Photo = req.files?.Photo ? req.files.Photo[0].buffer : req.body.Photo; const IsActive = req.body.IsActive; const LicCount = req.body.LicCount; const DateCreated = req.body.DateCreated; const CreatedBy = req.body.CreatedBy; const RecordChanged = req.body.RecordChanged; const LocationID = req.body.LocationID; const isValid = req.body.isValid; const isDeleted = req.body.isDeleted; console.log('Photo文件:', req.files?.Photo); console.log('UserFP文件:', req.files?.UserFP); // 数据库操作不变,注意存储二进制的话Photo、UserFP字段类型要设为BLOB/LONGBLOB db.query( "UPDATE usermst SET CmpnyCode=?,UserID=?,UserFullName=?,UserDetail=?,LoginID=?,Password=?,UserPin=?,UserEmailID=?,UserFP=?,Photo=?,IsActive=?,LicCount=?,DateCreated=?,CreatedBy=?,RecordChanged=?,LocationID=?,isValid=?,isDeleted=? WHERE UserID=?", [ CompanyCode, UserID, UserFullName, UserDetail, LoginID, Password, UserPin, UserEmailID, UserFP, Photo, IsActive, LicCount, DateCreated, CreatedBy, RecordChanged, LocationID, isValid, isDeleted, userid, ], (err, result) => { if (err) { console.log(err); res.status(500).send(err); return; } res.send(result); } ); });
如果仅需接收单个Photo文件,multer配置保持upload.single("Photo"),文件获取方式改为:
const Photo2 = req.file; const Photo = Photo2 ? Photo2.buffer : req.body.Photo;
内容的提问来源于stack exchange,提问作者Chirag Maurya
相关产品推荐
相关产品推荐

