Multer 没有上传,但它不会给我任何错误
Multer doesnt upload but it wont give me any errors
我正在使用 multer 上传图像以在我的应用程序中创建课程,我的课程有图像,我有一个从用户那里获取数据的表格。
我在中间件中使用 multer,并使用 upload.single('images')
将其添加到我的路由中,我从用户那里获取图像的字段名为 images,这意味着我已经从用户那里获取了图像。
当我单击保存按钮时,我不会收到任何错误,我的服务器将像卡在中间件中一样工作,当我转到我的上传文件夹时,我没有看到任何图像已加载!
如果我加载图像,我会将课程保存在我的数据库中,即 mongo。但是我也没有找到保存的课程。
我检查了 enctype="multipart/form-data"
,它在我的表格中。
这是我的 multer 中间件代码
const multer = require("multer");
const mkdirp = require("mkdirp");
const fs = require("fs");
const getDirImage = () => {
let year = new Date().getFullYear();
let month = new Date().getMonth() + 1;
let day = new Date().getDay();
return `./public/uploads/images/${year}/${month}/${day}`;
};
const ImageStorage = multer.diskStorage({
destination: (req, file, cb) => {
let dir = getDirImage();
mkdirp(dir).then(made => {
console.log(`File made on ${made}`);
});
},
filename: (req, file, cb) => {
let filePath = getDirImage() + "/" + file.originalname;
if (!fs.existsSync(filePath)) cb(null, file.originalname);
else cb(null, Date.now() + "-" + file.originalname);
},
});
const uploadImage = multer({
storage: ImageStorage,
limits: {
fileSize: 1024 * 1024 * 10,
},
});
module.exports = uploadImage;
这是我将它引用到我的路由控制器处理程序的中间件
router.post("/courses/create", upload.single("images"), convertFileToField.handle, courseValidator.handle(), courseController.storeCourse);
这是convertFileToField
代码
const middleware = require('./middleware');
class ConvertFiletoField extends middleware {
handle(req, res, next) {
if (!req.file)
req.body.images = undefined;
else
req.body.images = req.file.filename;
next();
}
}
module.exports = new ConvertFiletoField();
这是courseValidator
中间件代码
const validator = require('./validator');
const Course = require("app/models/Course");
const path = require("path");
const { check } = require("express-validator/check");
class courseValidator extends validator {
handle() {
return [
check("title")
.not()
.isEmpty()
.withMessage("فیلد عنوان نمیتواند خالی بماند")
.custom(async (value) => {
const course = await Course.findOne({ slug: this.slug(value)});
if (course) {
throw new Error('we have this course on our site !!!!')
}
}),
check('images')
.custom(async value => {
if (! value) {
throw new Error('You need to enter a course !');
}
let fileExt = ['.png', '.jpg', 'jpeg', '.svg'];
if (! fileExt.includes(path.extname(value)))
throw new Error('the course extention is not valid !');
}),
];
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g, "-");
}
}
module.exports = new courseValidator();
最后这是 post 路由处理程序
const controller = require("app/http/controllers/controller");
const Course = require("app/models/Course");
const fs = require('fs');
const path = require("path");
const sharp = require("sharp");
class courseController extends controller {
showCourses(req, res) {
const courses = Course.find({}).sort({ createdAt: -1 });
res.render("admin/courses/index", { courses: courses });
}
createCourse(req, res) {
res.render("admin/courses/create");
}
async storeCourse(req, res) {
let status = await this.validationData(req);
if (!status) {
// For Deleting the saved image because of having validation error
if (req.file)
fs.unlink(req.file.path, (err) => {
console.log(err);
});
return this.back(req, res);
}
// Create the Course
let images = this.imageResize(req.file);
const { title, type, body, price, tags } = req.body;
const newCourse = new Course({
user: req.user._id,
title,
type,
slug: this.slug(),
body,
images: JSON.stringify(images),
price,
tags,
});
await newCourse.save();
return res.redirect("/admin/courses");
}
imageResize(image) {
let imageInfo = path.parse(image.path);
let addressImage = {};
addressImage["original"] = `${imageInfo}/${image.filename}`;
const resize = (size) => {
let imageName = `${imageInfo.name}-${size}${imageInfo.ext}`;
addressImage[size] = this.getUrlImage(`${image.destination}/${imageName}`);
sharp(image.path)
.resize(size, null)
.toFile(`${image.destination}/${imageName}`)
};
[1080, 720, 480].map(resize);
}
getUrlImage(dir) {
return dir.substr(8);
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g, "-");
}
}
module.exports = new courseController();
我已尽我所能,并且尝试了所有加载图像的解决方案,但我的 courseValidation
中间件出现错误。
请说出任何与 multer 相关的解决方案。我试试看。
这里需要定义中间件函数
router.post("/courses/create", multerMiddleWare,..{...});
const multerMiddleWare = (req, res, next) => {
uploadImage(req, res,
(error) => {
if (!error) return next();
return next('error');
});
};
const uploadImage = multer({
storage: ImageStorage,
limits: {
fileSize: 1024 * 1024 * 10,
},
}).single("images");
在 diskStorage
的 destination
部分中,您必须 return 回调函数中的目录名称。您的中间件在此部分停止,因为您没有调用 cb
函数。
destination: (req, file, cb) => {
let dir = getDirImage();
mkdirp(dir).then(made => {
console.log(`File made on ${made}`);
cb(made)
});
}
我正在使用 multer 上传图像以在我的应用程序中创建课程,我的课程有图像,我有一个从用户那里获取数据的表格。
我在中间件中使用 multer,并使用 upload.single('images')
将其添加到我的路由中,我从用户那里获取图像的字段名为 images,这意味着我已经从用户那里获取了图像。
当我单击保存按钮时,我不会收到任何错误,我的服务器将像卡在中间件中一样工作,当我转到我的上传文件夹时,我没有看到任何图像已加载!
如果我加载图像,我会将课程保存在我的数据库中,即 mongo。但是我也没有找到保存的课程。
我检查了 enctype="multipart/form-data"
,它在我的表格中。
这是我的 multer 中间件代码
const multer = require("multer");
const mkdirp = require("mkdirp");
const fs = require("fs");
const getDirImage = () => {
let year = new Date().getFullYear();
let month = new Date().getMonth() + 1;
let day = new Date().getDay();
return `./public/uploads/images/${year}/${month}/${day}`;
};
const ImageStorage = multer.diskStorage({
destination: (req, file, cb) => {
let dir = getDirImage();
mkdirp(dir).then(made => {
console.log(`File made on ${made}`);
});
},
filename: (req, file, cb) => {
let filePath = getDirImage() + "/" + file.originalname;
if (!fs.existsSync(filePath)) cb(null, file.originalname);
else cb(null, Date.now() + "-" + file.originalname);
},
});
const uploadImage = multer({
storage: ImageStorage,
limits: {
fileSize: 1024 * 1024 * 10,
},
});
module.exports = uploadImage;
这是我将它引用到我的路由控制器处理程序的中间件
router.post("/courses/create", upload.single("images"), convertFileToField.handle, courseValidator.handle(), courseController.storeCourse);
这是convertFileToField
代码
const middleware = require('./middleware');
class ConvertFiletoField extends middleware {
handle(req, res, next) {
if (!req.file)
req.body.images = undefined;
else
req.body.images = req.file.filename;
next();
}
}
module.exports = new ConvertFiletoField();
这是courseValidator
中间件代码
const validator = require('./validator');
const Course = require("app/models/Course");
const path = require("path");
const { check } = require("express-validator/check");
class courseValidator extends validator {
handle() {
return [
check("title")
.not()
.isEmpty()
.withMessage("فیلد عنوان نمیتواند خالی بماند")
.custom(async (value) => {
const course = await Course.findOne({ slug: this.slug(value)});
if (course) {
throw new Error('we have this course on our site !!!!')
}
}),
check('images')
.custom(async value => {
if (! value) {
throw new Error('You need to enter a course !');
}
let fileExt = ['.png', '.jpg', 'jpeg', '.svg'];
if (! fileExt.includes(path.extname(value)))
throw new Error('the course extention is not valid !');
}),
];
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g, "-");
}
}
module.exports = new courseValidator();
最后这是 post 路由处理程序
const controller = require("app/http/controllers/controller");
const Course = require("app/models/Course");
const fs = require('fs');
const path = require("path");
const sharp = require("sharp");
class courseController extends controller {
showCourses(req, res) {
const courses = Course.find({}).sort({ createdAt: -1 });
res.render("admin/courses/index", { courses: courses });
}
createCourse(req, res) {
res.render("admin/courses/create");
}
async storeCourse(req, res) {
let status = await this.validationData(req);
if (!status) {
// For Deleting the saved image because of having validation error
if (req.file)
fs.unlink(req.file.path, (err) => {
console.log(err);
});
return this.back(req, res);
}
// Create the Course
let images = this.imageResize(req.file);
const { title, type, body, price, tags } = req.body;
const newCourse = new Course({
user: req.user._id,
title,
type,
slug: this.slug(),
body,
images: JSON.stringify(images),
price,
tags,
});
await newCourse.save();
return res.redirect("/admin/courses");
}
imageResize(image) {
let imageInfo = path.parse(image.path);
let addressImage = {};
addressImage["original"] = `${imageInfo}/${image.filename}`;
const resize = (size) => {
let imageName = `${imageInfo.name}-${size}${imageInfo.ext}`;
addressImage[size] = this.getUrlImage(`${image.destination}/${imageName}`);
sharp(image.path)
.resize(size, null)
.toFile(`${image.destination}/${imageName}`)
};
[1080, 720, 480].map(resize);
}
getUrlImage(dir) {
return dir.substr(8);
}
slug(title) {
return title.replace(/([^۰-۹آ-یa-z0-9]|-)+/g, "-");
}
}
module.exports = new courseController();
我已尽我所能,并且尝试了所有加载图像的解决方案,但我的 courseValidation
中间件出现错误。
请说出任何与 multer 相关的解决方案。我试试看。
这里需要定义中间件函数
router.post("/courses/create", multerMiddleWare,..{...});
const multerMiddleWare = (req, res, next) => {
uploadImage(req, res,
(error) => {
if (!error) return next();
return next('error');
});
};
const uploadImage = multer({
storage: ImageStorage,
limits: {
fileSize: 1024 * 1024 * 10,
},
}).single("images");
在 diskStorage
的 destination
部分中,您必须 return 回调函数中的目录名称。您的中间件在此部分停止,因为您没有调用 cb
函数。
destination: (req, file, cb) => {
let dir = getDirImage();
mkdirp(dir).then(made => {
console.log(`File made on ${made}`);
cb(made)
});
}