在 fetch API 中使用“multipart/form-data”发送 FormData 时面临问题

问题描述 投票:0回答:1

我有这张带有哈巴狗代码的表格

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 但没有任何结果

javascript node.js express multer sharp
1个回答
0
投票
//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);
    });
© www.soinside.com 2019 - 2024. All rights reserved.