Node.js Can';t在控制器中正确使用Multer(Node/Express.js)
我在使用Multer上传文件时遇到了问题,不幸的是,我对Multer没有太多经验。 在这个项目中,我试图构建一些东西,比如路由调用运行命令的函数(控制器),例如创建产品等等 我很确定我正确地设置了Multer,但是当我尝试在控制器中req.file.filename时,它会返回一个未定义的值 这是我的设置(目前Multer是一个助手函数,之后我将把它移到中间件中,因为这是不正确的) 文件存储辅助功能Node.js Can';t在控制器中正确使用Multer(Node/Express.js),node.js,express,multer,Node.js,Express,Multer,我在使用Multer上传文件时遇到了问题,不幸的是,我对Multer没有太多经验。 在这个项目中,我试图构建一些东西,比如路由调用运行命令的函数(控制器),例如创建产品等等 我很确定我正确地设置了Multer,但是当我尝试在控制器中req.file.filename时,它会返回一个未定义的值 这是我的设置(目前Multer是一个助手函数,之后我将把它移到中间件中,因为这是不正确的) 文件存储辅助功能 const multer = require("multer"); //S
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 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);
}
});
我知道在routes中执行此操作的传统方法如下(这很有效!)
然而,正如我上面提到的,我试图将路由操作分解为控制器函数。
当console.log(req.file)返回未定义的
我怀疑这些道具没有被传递到postProduct函数,这就是导致错误的原因,但我不知道如何解决这个问题。我已经盯着这个太久了,也许这是一件容易解决的事情,我很愚蠢(很可能)
如果有人能帮我解决这个问题,并解释我哪里出了问题,我将永远感激
编辑:这是错误:“TypeError:无法读取未定义的”的属性“filename”此语句:
return console.log(req.file)
中的postProduct
阻止其余代码运行并返回void
。始终返回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 }));
console.log()
的返回类型是void
。这就是函数返回未定义的的原因。控制台上的输出是否也未定义?是的,它也返回未定义。您好,我这样做是因为在放置console.log之前,它不会继续,因为req.file.filename未定义。所以我想看看这个文件是否被注册(事实并非如此)。当我删除上述问题时,问题就出现了。完整错误:“TypeError:无法读取未定义的属性'filename'”为了清晰起见,我将其添加到文章底部。我明白了。这可能与expressAsyncHandler
有关。尝试从postProduct
中删除它,并在路由中使用它:.post(“/”,uploadOptions.single(“image”),expressAsyncHandler(postProduct))
只是为了澄清一下,使用multer的传统方法是处理完全相同的请求吗?然后我们可以排除前端、文件和其他东西。嘿-我只是尝试了一下,可惜没有成功:(-如果有帮助,这里是回复:为什么这是公认的答案?OP说他是在处理文件上传(多部分/表单数据),而不是urlencoded实体(application/x-www-form-urlencoded)。
// this is for parsing json data
app.use(express.json());
// this is for parsing form data
app.use(express.urlencoded({ extended: false }));