上传图片,然后使用 Multer 和 Express.js 进行更新

Upload image then update with Multer and Express.js

所以我已经完成了Multer and Express.js from here上传图片的阶段。现在,如果我编辑具有该图像的文章,我会得到正确的图像。但是,我想做的是,如果图像仍然相同,请不要做任何事情,否则使用新上传的图像。

我的问题是 input[type="file"] 不接受手动设置 attr value。我也读了这个 但我不知道它是否与我的问题相关!

提交编辑后得到的是Cannot read property 'filename' of undefined。然而,我从请求中正确获取了所有其他表单字段。

我正在使用 Mongoose and methodOverride for PUT and DELETE requests

穆尔特

const multer = require('multer');
const storage = multer.diskStorage({
  destination: (_req, _file, done) => {
    done(null, path.join(__dirname, './../../public/uploads/'));
  },
  filename: (_req, file, done) => {
    done(
      null,
      `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`,
    );
  },
});
const upload = multer({
  storage
});

对于POST请求

router.post('/add', authenticate, upload.single('image'), (req, res) => {

    const userId = req.user.id;

    const body = req.body;

    const title = body.title;
    const content = body.content;
    const featured = body.featured;
    const image = req.file.filename;

    const newPost = new Post({
      title,
      content,
      image,
      userId,
      featured
    });

    newPost
      .save()
      .then(post => {
        if (!post) {
          return req.flash('error', 'Unable to add article!!!');
        }
        req.flash('success', 'Added article successfully');
      })
      .catch(err => {
        return req.flash('error', 'Unable to add article!!!');
      });

    res.redirect('/posts');
  },
);

对于 PUT 请求

router.put(/post/edit/:id', authenticate, upload.single('image'), (req, res) => {
    const id = req.params.id;

const body = req.body;

console.log('body:', body);
console.log('req:', req);

const title = body.title;
const content = body.content;
const featured = body.featured;
const image = req.file.filename;

Post.findOneAndUpdate(id,
  {
    $set: {
      title,
      content,
      featured,
      image
    }
  },
  { new: true }
).then(post => {
    req.flash('success', 'Edits submitted successfully');
    res.redirect('/posts');
  })
  .catch(err => {
    return req.flash('error', 'Unable to edit article');
  }); });
const multer = require('multer');

 var storage = multer.diskStorage({
    destination: (req, file, callback) => {
    callback(null, 'public/uploads/')
 },
 filename: (req, file, callback) => {
    var filetype = file.mimetype;
    var fileformate = filetype.split("/")[1];
    callback(null, Date.now() + '.' + fileformate);
 }
});
var upload = multer({ storage: storage });

您只需使用 if (req.file) 检查是否有附加到请求的文件并相应地修改数据库查询。 所以你的 post 编辑代码可以像这样:

router.put('/post/edit/:id', authenticate, upload.single('image'), (req, res) => {
    const id = req.params.id;

    const body = req.body;

    console.log('body:', body);
    console.log('req:', req);


    const title = body.title;
    const content = body.content;
    const featured = body.featured;

    const updates = {
        title,
        content,
        featured
    };

    if (req.file) {
        const image = req.file.filename;
        updates.image = image;
    }


    Post.findOneAndUpdate(id, {
            $set: updates
        }, {
            new: true
        }).then(post => {
            req.flash('success', 'Edits submitted successfully');
            res.redirect('/posts');
        })
        .catch(err => {
            return req.flash('error', 'Unable to edit article');
        });
});

来自 multer.single(fieldname)

的文档

Accept a single file with the name fieldname. The single file will be stored in req.file.


因为你正在做 upload.single('image') 你的 multer 将接受带有 name 图像 的文件并将其存储到 req.file.image。但是,您使用 filename 引用它。因此,您应该将 req.file.filename 替换为 req.file.image.

此外,在上传新文件或编辑时,您需要在使用 multer 处理之前检查 file 是否存在,以避免 属性 未定义错误。

if (req.file) {
  // your code
}