无法在控制器中正确使用 Multer (Node/Express.js)

Can't Use Multer Properly In A Controller (Node/Express.js)

我在使用 Multer 上传文件时遇到问题,不幸的是,我对 Multer 的使用经验不多。 在这个项目中,我试图构建一些东西,以便路由调用 运行 命令的函数(控制器),例如创建产品等

我很确定我正确设置了 Multer,但是当我尝试在控制器中 req.file.filename 它 returns 未定义。

这是我的设置(目前 Multer 是一个辅助函数,我将把它移到中间件,因为这是不正确的)。

文件存储助手功能

const multer = require("multer");

//SET Storage
let storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "public/uploads");
  },
  filename: function (req, file, cb) {
    const fileName = file.originalname.replace(" ", "-");
    cb(null, fileName + "-" + Date.now());
  },
});
const uploadOptions = multer({ storage });

module.exports = { uploadOptions };

产品路由器

const express = require("express");
const router = express.Router();

//@Helpers
const { uploadOptions } = require("./../../Helpers/FileStorage.helper");

//@Categories
const {
  getProducts,
  postProduct
} = require("./../../Controllers/Products/product.controller");

//GET ALL Products + ADD NEW Product
router
  .get("/", getProducts)
  .post("/", uploadOptions.single("image"), postProduct);

最后,post产品控制器:

//POST A New Product
const postProduct = expressAsyncHandler(async (req, res) => {
  const category = await Categories.findOne(req.body.category);
  if (!category) return res.status(400).send("Category is invalid, try again!");


  const fileName = req.file.filename;
  const basePath = `${req.protocol}://${req.get("host")}/public/upload/`;

  const product = new Product({
    name: req.body.name,
    description: req.body.description,
    richDescription: req.body.richDescription,
    image: `${basePath}${fileName}`,
    brand: req.body.brand,
    price: req.body.price,
    category,
    countInStock: req.body.countInStock,
    rating: req.body.rating,
    numReviews: req.body.numReviews,
    isFeatured: req.body.isFeatured,
  });
  const productList = await Product.findOne({ name: product.name });
  if (productList != null) {
    return res.status(404).send("Product already exists! Please try again!");
  }
  try {
    await product.save();
    res.status(200).send(product);
  } catch (e) {
    res.status(500).send("Product was not created! Error: " + e.message);
  }
});

我知道在路线中执行此操作的传统方法如下(有效!):

router.post("/", uploadOptions.single("image"), async(req,res) => {
//Run function
}

但是,正如我上面提到的,我正在尝试将路由操作分解为控制器功能。 当 console.log(req.file) 它 returns 未定义。

我怀疑 props 没有传递给 postProduct 函数,这是导致错误的原因,但我不知道如何解决这个问题。我已经盯着这个看太久了,也许这是一件容易解决的事情,我很愚蠢(很有可能)。

如果有人可以帮助我解决这个问题并解释我哪里出错了,我将永远感激不已。

编辑:这是错误:“TypeError:无法读取未定义的 属性'filename'

此语句:postProduct 中的 return console.log(req.file) 阻止了其余代码 运行ning 和 returns voidConsole.log 总是 returns void.

如果您只想记录文件并继续执行其余功能,请删除 return 关键字:console.log(req.file).

当您 运行 应用程序时,终端中的 console.log 输出什么?

我认为您没有正确解析表单数据:

// this is for parsing json data
app.use(express.json());
// this is for parsing form data
app.use(express.urlencoded({ extended: false }));