无法在控制器中正确使用 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 void
。 Console.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 }));
我在使用 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 void
。 Console.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 }));