我有这张带有哈巴狗代码的表格
form.form.form-user-data
.form__group
label.form__label(for='name') Name
input#name.form__input(type='text', value=`${user.name}`, required)
.form__group.ma-bt-md
label.form__label(for='email') Email address
input#email.form__input(type='email', value=`${user.email}`, required)
.form__group.form__photo-upload
img.form__user-photo(src=`/img/users/${user.photo}`, alt=`Photo of${user.name}`)
input.form__upload(type='file' accept='image/*' id='photo' name='photo' )
label(for='photo') Choose new photo
这是 Node&Epress 的后端
const multerStorage = multer.memoryStorage();
const multerFitler = (req, file, cb) => {
if (file.mimetype.startsWith('image')) {
cb(null, true);
} else cb(new AppError('Not an image! Please upload an image.', 400));
};
const upload = multer({
storage: multerStorage,
fileFilter: multerFitler,
});
exports.uploadUserPhoto = upload.single('photo');
exports.resizeUserPhoto = (req, res, next) => {
if (!req.file) return next();
req.file.filename = `user-${req.user._id}-${Date.now()}.jpeg`;
// console.log(req.file);
sharp(req.file.buffer)
.resize(500, 500)
.toFormat('jpeg')
.jpeg({ quality: 90 })
.toFile(`public/img/users/${req.file.filename}`);
next();
};
function filterObj(obj, ...allowedFields) {
const newObj = {};
Object.keys(obj).forEach((key) => {
if (allowedFields.includes(key)) newObj[key] = obj[key];
});
return newObj;
}
exports.updateMe = catchAsync(async (req, res, next) => {
if (req.body.password || req.body.passwrodConfirm)
return next(
new AppError(
'This route is not for password updates. Please use /updatePassword route',
400,
),
);
const filterdBody = filterObj(req.body, 'name', 'email');
if (req.file) filterdBody.photo = req.file.filename;
const updatedUser = await User.findByIdAndUpdate(req.user._id, filterdBody, {
new: true,
runValidators: true,
});
res.status(200).json({
status: 'success',
data: {
user: updatedUser,
},
});
});
这是我处理请求的路线
router.patch('/updateMe', uploadUserPhoto, resizeUserPhoto, updateMe);
这是我的前端代码
async function updateData(endpoint, body) {
const res = await fetch(`http://127.0.0.1:3000/api/v1/users/${endpoint}`, {
method: 'PATCH',
body,
});
const data = await res.json();
console.log(data);
}
updateDataForm.addEventListener('submit', (e) => {
e.preventDefault();
const form = new FormData(updateDataForm);
form.append('name', updateNameInput.value);
form.append('email', updateEmailInput.value);
form.append('photo', updatePhotoInput.files[0]);
updateData('updateMe', form);
});
console.log(data) 给了我这个错误
{ 代码:“LIMIT_UNEXPECTED_FILE” 字段:“照片” 消息:“意外字段” 名称:“穆特错误” }
这个错误来自浏览器,但 Postman 工作得很好
我尝试将标头添加到获取选项对象
headers: { 'Content-Type': 'multipart/form-data' }
但这是另一个错误
{
message: 'Multipart: Boundary not found'
}
在 Postman 'multipart/form-data;边界=发送请求时计算'
这只是从浏览器请求 URL 时发生的错误我已经询问了 Chatgpt 但没有任何结果
//Why are you adding 'updateDataForm' in FormData try after removing it.
async function updateData(endpoint, body) {
const res = await fetch(`http://127.0.0.1:3000/api/v1/users/${endpoint}`, {
method: 'PATCH',
body,
});
const data = await res.json();
console.log(data);
}
updateDataForm.addEventListener('submit', (e) => {
e.preventDefault();
const form = new FormData();
form.append('name', updateNameInput.value);
form.append('email', updateEmailInput.value);
form.append('photo', updatePhotoInput.files[0]);
updateData('updateMe', form);
});