Node.js 如何在nodejs的控制器内调用multer中间件?
我正在尝试在我的服务器中上载图像。 在前端,我与Angular合作。 前端工作正常,我只是想告诉你我是如何将文件传递到后端的 component.html upload.service.ts-功能Node.js 如何在nodejs的控制器内调用multer中间件?,node.js,mean-stack,image-uploading,multer,Node.js,Mean Stack,Image Uploading,Multer,我正在尝试在我的服务器中上载图像。 在前端,我与Angular合作。 前端工作正常,我只是想告诉你我是如何将文件传递到后端的 component.html upload.service.ts-功能 imagem: File; constructor(private uploadService: UploadService) { } onChange(event) { this.imagem = event.target.files[0]; } onSubmit()
imagem: File;
constructor(private uploadService: UploadService) { }
onChange(event) {
this.imagem = event.target.files[0];
}
onSubmit() {
this.uploadService.upload(this.imagem);
}
constructor(private http: HttpClient) { }
upload(file: File) {
const formData = new FormData();
formData.append('img', file, file.name);
this.http.post(environment.apiBaseUrl + '/upload', formData, {responseType: 'text'}).subscribe(
res => console.log('Done')
);
}
在后端,我有以下结构:
app.js
index.router.js
upload.controller.js
我尝试调用路由中的中间件,但我认为它不正确,也没有达到目标。Algo,上传不是一个。
在服务器端,我得到:{}未定义作为结果,这可能意味着multer没有处理该文件。
在客户端,我完成了
那么我做错了什么?我如何才能使它与这种后端结构一起工作?Express Middleware设计为在路由级别安装。事实上,在MVC模型中,express程序员亲自调用控制器路由,而不是在代码中调用路由。从传统的MVC框架来看,将控制器和路由分开它们都意味着同一件事没有意义,但是如果你愿意,你可以这样做 要按设计使用multer,您需要在index.router.js中执行此操作: index.router.js 然后需要从upload.controller.js中删除所有与multer相关的代码 但是,您可以坚持在upload.controller.js中执行此操作。这里的关键是理解什么是中间产品 在Express中,中间件是具有以下原型的函数:
function (req, res, next) { // next is optional
// middleware logic
}
是的,没错。upload.controller.js文件中的代码是一个中间件。您自己编写的中间件恰好位于中间件链的末端
你看,Express只接受中间产品。快车没有别的了。路线是恰好在终点的中间产品
Express.use、.get、.post和相关方法接受无限多个参数。第一个参数是可选的路由说明符,但不是必需的,其余参数是中间件。例如:
app.get('/foo',
(req, res, next) => {
// first middleware
next(); // next is what allows processing to continue
},
(req, res, next) => {
// second middleware
next();
},
(req, res, next) => {
res.send('hello'); // controller logic - a controller
// is just the last middleware
// Note: if you call next() instead of res.send() in a
// controller express will respond with a 500 internal
// server error status with whatever string you pass
// to next() as the error message.
}
);
知道了这一点,我们知道upload.single'img'函数返回什么。该函数不执行中间件逻辑。相反,它返回中间件函数:
let middleware = upload.single('img');
// middleware is now a function with the prototype:
// (req, res, next) => {}
因此,要执行中间件逻辑,我们必须将其称为express,它会自动将其作为路由处理的一部分进行调用,就像它如何调用控制器功能一样,但如果我们想自己执行,我们可以
如果要在upload.controller.js中实现中间件,需要执行以下操作:
那东西太多了。如果我们稍微重构一下代码,就可以使代码更容易理解:
let middleware = upload.single('img');
module.exports.send = (req, res, next) => {
// Define the controller here to capture
// req and res in a closure:
let controller = () => {
console.log(req.body, req.files);
res.send('ok');
};
middleware(req, res, controller); // call the middleware with
// our controller as callback
}
但是这是非常不标准的,对于一个经验丰富的Express.js程序员来说是非常意外的。即使有可能,我也不会这么做。它还将中间件与控制器紧密耦合,完全否定了Express中间件配置系统的灵活性。Express中间件旨在安装在路由级别。事实上,在MVC模型中,express程序员亲自调用控制器路由,而不是在代码中调用路由。从传统的MVC框架来看,将控制器和路由分开它们都意味着同一件事没有意义,但是如果你愿意,你可以这样做 要按设计使用multer,您需要在index.router.js中执行此操作: index.router.js 然后需要从upload.controller.js中删除所有与multer相关的代码 但是,您可以坚持在upload.controller.js中执行此操作。这里的关键是理解什么是中间产品 在Express中,中间件是具有以下原型的函数:
function (req, res, next) { // next is optional
// middleware logic
}
是的,没错。upload.controller.js文件中的代码是一个中间件。您自己编写的中间件恰好位于中间件链的末端
你看,Express只接受中间产品。快车没有别的了。路线是恰好在终点的中间产品
Express.use、.get、.post和相关方法接受无限多个参数。第一个参数是可选的路由说明符,但不是必需的,其余参数是中间件。例如:
app.get('/foo',
(req, res, next) => {
// first middleware
next(); // next is what allows processing to continue
},
(req, res, next) => {
// second middleware
next();
},
(req, res, next) => {
res.send('hello'); // controller logic - a controller
// is just the last middleware
// Note: if you call next() instead of res.send() in a
// controller express will respond with a 500 internal
// server error status with whatever string you pass
// to next() as the error message.
}
);
知道了这一点,我们知道upload.single'img'函数返回什么。该函数不执行中间件逻辑。相反,它返回中间件函数:
let middleware = upload.single('img');
// middleware is now a function with the prototype:
// (req, res, next) => {}
因此,要执行中间件逻辑,我们必须将其称为express,它会自动将其作为路由处理的一部分进行调用,就像它如何调用控制器功能一样,但如果我们想自己执行,我们可以
如果要在upload.controller.js中实现中间件,需要执行以下操作:
那东西太多了。如果我们稍微重构一下代码,就可以使代码更容易理解:
let middleware = upload.single('img');
module.exports.send = (req, res, next) => {
// Define the controller here to capture
// req and res in a closure:
let controller = () => {
console.log(req.body, req.files);
res.send('ok');
};
middleware(req, res, controller); // call the middleware with
// our controller as callback
}
但是这是非常不标准的,对于一个经验丰富的Express.js程序员来说是非常意外的。即使有可能,我也不会这么做。它还与中间件紧密耦合
您的控制器完全否定了Express中间件配置系统非常灵活的特性。一个基于@slebetman答案的Multer中间件分离文件的示例 /middleware/multer.js 这样可以避免错误文件类型的状态为500
希望这对某人有所帮助:D一个基于@slebetman答案的Multer中间件分离文件的示例 /middleware/multer.js 这样可以避免错误文件类型的状态为500 希望这对某人有帮助:D
module.exports.send = (req, res, next) => {
upload.single('img')(req, res, () => {
// Remember, the middleware will call it's next function
// so we can inject our controller manually as the next()
console.log(req.body, req.files);
res.send('ok');
});
}
let middleware = upload.single('img');
module.exports.send = (req, res, next) => {
// Define the controller here to capture
// req and res in a closure:
let controller = () => {
console.log(req.body, req.files);
res.send('ok');
};
middleware(req, res, controller); // call the middleware with
// our controller as callback
}
const multer = require('multer')
const ErrorMessages = require('../constants/ErrorMessages')
function makeid (length) {
var result = ''
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
var charactersLength = characters.length
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength))
}
return result
}
const DIR = './uploads/'
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, DIR)
},
filename: (req, file, cb) => {
const fileName = file.originalname.toLowerCase().split(' ').join('-')
cb(null, makeid(16) + '_' + fileName)
}
})
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (file.mimetype === 'image/png' || file.mimetype === 'application/pdf') {
cb(null, true)
} else {
cb(null, false)
return cb(new Error('Only .png, .jpg, .mp4 and .jpeg format allowed!'))
}
}
})
module.exports.send = (req, res, next) => {
return upload.single('file')(req, res, () => {
// Remember, the middleware will call it's next function
// so we can inject our controller manually as the next()
if (!req.file) return res.json({ error: ErrorMessages.invalidFiletype })
next()
})
}
routes.post('/object', multer.send, ObjectController.createObject)